
<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>tigramite.pcmci &#8212; Tigramite 5.2 documentation</title>
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
    <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
    <script src="../../_static/jquery.js"></script>
    <script src="../../_static/underscore.js"></script>
    <script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
    <script src="../../_static/doctools.js"></script>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
   
  <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
  
  
  <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />

  </head><body>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          

          <div class="body" role="main">
            
  <h1>Source code for tigramite.pcmci</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;Tigramite causal discovery for time series.&quot;&quot;&quot;</span>

<span class="c1"># Author: Jakob Runge &lt;jakob@jakob-runge.com&gt;</span>
<span class="c1">#</span>
<span class="c1"># License: GNU General Public License v3.0</span>

<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
<span class="kn">import</span> <span class="nn">warnings</span>
<span class="kn">import</span> <span class="nn">itertools</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="kn">from</span> <span class="nn">copy</span> <span class="kn">import</span> <span class="n">deepcopy</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">scipy.stats</span>

<span class="kn">from</span> <span class="nn">.pcmci_base</span> <span class="kn">import</span> <span class="n">PCMCIbase</span>

<span class="k">def</span> <span class="nf">_create_nested_dictionary</span><span class="p">(</span><span class="n">depth</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">lowest_type</span><span class="o">=</span><span class="nb">dict</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Create a series of nested dictionaries to a maximum depth.  The first</span>
<span class="sd">    depth - 1 nested dictionaries are defaultdicts, the last is a normal</span>
<span class="sd">    dictionary.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    depth : int</span>
<span class="sd">        Maximum depth argument.</span>
<span class="sd">    lowest_type: callable (optional)</span>
<span class="sd">        Type contained in leaves of tree.  Ex: list, dict, tuple, int, float ...</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">new_depth</span> <span class="o">=</span> <span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span>
    <span class="k">if</span> <span class="n">new_depth</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">lowest_type</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">defaultdict</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">_create_nested_dictionary</span><span class="p">(</span><span class="n">new_depth</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">_nested_to_normal</span><span class="p">(</span><span class="n">nested_dict</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Transforms the nested default dictionary into a standard dictionaries</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    nested_dict : default dictionary of default dictionaries of ... etc.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">nested_dict</span><span class="p">,</span> <span class="n">defaultdict</span><span class="p">):</span>
        <span class="n">nested_dict</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">_nested_to_normal</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">nested_dict</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
    <span class="k">return</span> <span class="n">nested_dict</span>


<div class="viewcode-block" id="PCMCI"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI">[docs]</a><span class="k">class</span> <span class="nc">PCMCI</span><span class="p">(</span><span class="n">PCMCIbase</span><span class="p">):</span>
<span class="w">    </span><span class="sa">r</span><span class="sd">&quot;&quot;&quot;PCMCI causal discovery for time series datasets.</span>

<span class="sd">    PCMCI is a causal discovery framework for large-scale time series</span>
<span class="sd">    datasets. This class contains several methods. The standard PCMCI method</span>
<span class="sd">    addresses time-lagged causal discovery and is described in Ref [1] where</span>
<span class="sd">    also further sub-variants are discussed. Lagged as well as contemporaneous</span>
<span class="sd">    causal discovery is addressed with PCMCIplus and described in [5]. See the</span>
<span class="sd">    tutorials for guidance in applying these methods.</span>

<span class="sd">    PCMCI has:</span>

<span class="sd">    * different conditional independence tests adapted to linear or</span>
<span class="sd">      nonlinear dependencies, and continuously-valued or discrete data (</span>
<span class="sd">      implemented in ``tigramite.independence_tests``)</span>
<span class="sd">    * (mostly) hyperparameter optimization</span>
<span class="sd">    * easy parallelization (separate script)</span>
<span class="sd">    * handling of masked time series data</span>
<span class="sd">    * false discovery control and confidence interval estimation</span>


<span class="sd">    Notes</span>
<span class="sd">    -----</span>

<span class="sd">    .. image:: mci_schematic.*</span>
<span class="sd">       :width: 200pt</span>

<span class="sd">    In the PCMCI framework, the dependency structure of a set of time series</span>
<span class="sd">    variables is represented in a *time series graph* as shown in the Figure.</span>
<span class="sd">    The nodes of a time series graph are defined as the variables at</span>
<span class="sd">    different times and a link indicates a conditional dependency that can be</span>
<span class="sd">    interpreted as a causal dependency under certain assumptions (see paper).</span>
<span class="sd">    Assuming stationarity, the links are repeated in time. The parents</span>
<span class="sd">    :math:`\mathcal{P}` of a variable are defined as the set of all nodes</span>
<span class="sd">    with a link towards it (blue and red boxes in Figure).</span>

<span class="sd">    The different PCMCI methods estimate causal links by iterative</span>
<span class="sd">    conditional independence testing. PCMCI can be flexibly combined with</span>
<span class="sd">    any kind of conditional independence test statistic adapted to the kind</span>
<span class="sd">    of data (continuous or discrete) and its assumed dependency types.</span>
<span class="sd">    These are available in ``tigramite.independence_tests``.</span>

<span class="sd">    NOTE: MCI test statistic values define a particular measure of causal</span>
<span class="sd">    strength depending on the test statistic used. For example, ParCorr()</span>
<span class="sd">    results in normalized values between -1 and 1. However, if you are </span>
<span class="sd">    interested in quantifying causal effects, i.e., the effect of</span>
<span class="sd">    hypothetical interventions, you may better look at the causal effect </span>
<span class="sd">    estimation functionality of Tigramite.</span>

<span class="sd">    References</span>
<span class="sd">    ----------</span>

<span class="sd">    [1] J. Runge, P. Nowack, M. Kretschmer, S. Flaxman, D. Sejdinovic,</span>
<span class="sd">           Detecting and quantifying causal associations in large nonlinear time </span>
<span class="sd">           series datasets. Sci. Adv. 5, eaau4996 (2019) </span>
<span class="sd">           https://advances.sciencemag.org/content/5/11/eaau4996</span>

<span class="sd">    [5] J. Runge,</span>
<span class="sd">           Discovering contemporaneous and lagged causal relations in </span>
<span class="sd">           autocorrelated nonlinear time series datasets</span>
<span class="sd">           http://www.auai.org/~w-auai/uai2020/proceedings/579_main_paper.pdf</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    dataframe : data object</span>
<span class="sd">        This is the Tigramite dataframe object. Among others, it has the</span>
<span class="sd">        attributes dataframe.values yielding a numpy array of shape (</span>
<span class="sd">        observations T, variables N) and optionally a mask of the same shape.</span>
<span class="sd">    cond_ind_test : conditional independence test object</span>
<span class="sd">        This can be ParCorr or other classes from</span>
<span class="sd">        ``tigramite.independence_tests`` or an external test passed as a</span>
<span class="sd">        callable. This test can be based on the class</span>
<span class="sd">        tigramite.independence_tests.CondIndTest.</span>
<span class="sd">    verbosity : int, optional (default: 0)</span>
<span class="sd">        Verbose levels 0, 1, ...</span>

<span class="sd">    Attributes</span>
<span class="sd">    ----------</span>
<span class="sd">    all_parents : dictionary</span>
<span class="sd">        Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...} containing</span>
<span class="sd">        the conditioning-parents estimated with PC algorithm.</span>
<span class="sd">    val_min : dictionary</span>
<span class="sd">        Dictionary of form val_min[j][(i, -tau)] = float</span>
<span class="sd">        containing the minimum test statistic value for each link estimated in</span>
<span class="sd">        the PC algorithm.</span>
<span class="sd">    pval_max : dictionary</span>
<span class="sd">        Dictionary of form pval_max[j][(i, -tau)] = float containing the maximum</span>
<span class="sd">        p-value for each link estimated in the PC algorithm.</span>
<span class="sd">    iterations : dictionary</span>
<span class="sd">        Dictionary containing further information on algorithm steps.</span>
<span class="sd">    N : int</span>
<span class="sd">        Number of variables.</span>
<span class="sd">    T : dict</span>
<span class="sd">        Time series sample length of dataset(s).</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="p">,</span>
                 <span class="n">cond_ind_test</span><span class="p">,</span>
                 <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>

        <span class="c1"># Init base class</span>
        <span class="n">PCMCIbase</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataframe</span><span class="o">=</span><span class="n">dataframe</span><span class="p">,</span> 
                        <span class="n">cond_ind_test</span><span class="o">=</span><span class="n">cond_ind_test</span><span class="p">,</span>
                        <span class="n">verbosity</span><span class="o">=</span><span class="n">verbosity</span><span class="p">)</span>


    <span class="k">def</span> <span class="nf">_iter_conditions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">conds_dim</span><span class="p">,</span> <span class="n">all_parents</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Yield next condition.</span>

<span class="sd">        Yields next condition from lexicographically ordered conditions.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        parent : tuple</span>
<span class="sd">            Tuple of form (i, -tau).</span>
<span class="sd">        conds_dim : int</span>
<span class="sd">            Cardinality in current step.</span>
<span class="sd">        all_parents : list</span>
<span class="sd">            List of form [(0, -1), (3, -2), ...].</span>

<span class="sd">        Yields</span>
<span class="sd">        -------</span>
<span class="sd">        cond :  list</span>
<span class="sd">            List of form [(0, -1), (3, -2), ...] for the next condition.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">all_parents_excl_current</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">all_parents</span> <span class="k">if</span> <span class="n">p</span> <span class="o">!=</span> <span class="n">parent</span><span class="p">]</span>
        <span class="k">for</span> <span class="n">cond</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">(</span><span class="n">all_parents_excl_current</span><span class="p">,</span> <span class="n">conds_dim</span><span class="p">):</span>
            <span class="k">yield</span> <span class="nb">list</span><span class="p">(</span><span class="n">cond</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_sort_parents</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parents_vals</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Sort current parents according to test statistic values.</span>

<span class="sd">        Sorting is from strongest to weakest absolute values.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ---------</span>
<span class="sd">        parents_vals : dict</span>
<span class="sd">            Dictionary of form {(0, -1):float, ...} containing the minimum test</span>
<span class="sd">            statistic value of a link.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        parents : list</span>
<span class="sd">            List of form [(0, -1), (3, -2), ...] containing sorted parents.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Sorting parents in decreasing order with &quot;</span>
                  <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    weight(i-tau-&gt;j) = min_</span><span class="si">{iterations}</span><span class="s2"> |val_</span><span class="si">{ij}</span><span class="s2">(tau)| &quot;</span><span class="p">)</span>
        <span class="c1"># Get the absolute value for all the test statistics</span>
        <span class="n">abs_values</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">parents_vals</span><span class="p">[</span><span class="n">k</span><span class="p">])</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">parents_vals</span><span class="p">)}</span>
        <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">abs_values</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">abs_values</span><span class="o">.</span><span class="n">get</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_print_link_info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">index_parent</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">num_parents</span><span class="p">,</span>
                         <span class="n">already_removed</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print info about the current link being tested.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        j : int</span>
<span class="sd">            Index of current node being tested.</span>
<span class="sd">        index_parent : int</span>
<span class="sd">            Index of the current parent.</span>
<span class="sd">        parent : tuple</span>
<span class="sd">            Standard (i, tau) tuple of parent node id and time delay</span>
<span class="sd">        num_parents : int</span>
<span class="sd">            Total number of parents.</span>
<span class="sd">        already_removed : bool</span>
<span class="sd">            Whether parent was already removed.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">link_marker</span> <span class="o">=</span> <span class="p">{</span><span class="kc">True</span><span class="p">:</span><span class="s2">&quot;o?o&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span><span class="s2">&quot;-?&gt;&quot;</span><span class="p">}</span>

        <span class="n">abstau</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">parent</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Link (</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%d</span><span class="s2">/</span><span class="si">%d</span><span class="s2">):&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">parent</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">parent</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">link_marker</span><span class="p">[</span><span class="n">abstau</span><span class="o">==</span><span class="mi">0</span><span class="p">],</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                <span class="n">index_parent</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">num_parents</span><span class="p">))</span>

            <span class="k">if</span> <span class="n">already_removed</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;    Already removed.&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_print_cond_info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">Z</span><span class="p">,</span> <span class="n">comb_index</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print info about the condition</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        Z : list</span>
<span class="sd">            The current condition being tested.</span>
<span class="sd">        comb_index : int</span>
<span class="sd">            Index of the combination yielding this condition.</span>
<span class="sd">        pval : float</span>
<span class="sd">            p-value from this condition.</span>
<span class="sd">        val : float</span>
<span class="sd">            value from this condition.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">var_name_z</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
        <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">:</span>
            <span class="n">var_name_z</span> <span class="o">+=</span> <span class="s2">&quot;(</span><span class="si">%s</span><span class="s2"> </span><span class="si">% .2s</span><span class="s2">) &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">tau</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">Z</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> <span class="n">var_name_z</span> <span class="o">=</span> <span class="s2">&quot;()&quot;</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;    Subset </span><span class="si">%d</span><span class="s2">: </span><span class="si">%s</span><span class="s2"> gives pval = </span><span class="si">%.5f</span><span class="s2"> / val = </span><span class="si">% .3f</span><span class="s2">&quot;</span> <span class="o">%</span>
              <span class="p">(</span><span class="n">comb_index</span><span class="p">,</span> <span class="n">var_name_z</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">val</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">_print_a_pc_result</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nonsig</span><span class="p">,</span> <span class="n">conds_dim</span><span class="p">,</span> <span class="n">max_combinations</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print the results from the current iteration of conditions.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        nonsig : bool</span>
<span class="sd">            Indicate non-significance.</span>
<span class="sd">        conds_dim : int</span>
<span class="sd">            Cardinality of the current step.</span>
<span class="sd">        max_combinations : int</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Start with an indent</span>
        <span class="n">print_str</span> <span class="o">=</span> <span class="s2">&quot;    &quot;</span>
        <span class="c1"># Determine the body of the text</span>
        <span class="k">if</span> <span class="n">nonsig</span><span class="p">:</span>
            <span class="n">print_str</span> <span class="o">+=</span> <span class="s2">&quot;Non-significance detected.&quot;</span>
        <span class="k">elif</span> <span class="n">conds_dim</span> <span class="o">&gt;</span> <span class="n">max_combinations</span><span class="p">:</span>
            <span class="n">print_str</span> <span class="o">+=</span> <span class="s2">&quot;Still subsets of dimension&quot;</span> <span class="o">+</span> \
                         <span class="s2">&quot; </span><span class="si">%d</span><span class="s2"> left,&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">conds_dim</span><span class="p">)</span> <span class="o">+</span> \
                         <span class="s2">&quot; but q_max = </span><span class="si">%d</span><span class="s2"> reached.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">max_combinations</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">print_str</span> <span class="o">+=</span> <span class="s2">&quot;No conditions of dimension </span><span class="si">%d</span><span class="s2"> left.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">conds_dim</span><span class="p">)</span>
        <span class="c1"># Print the message</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">print_str</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_print_converged_pc_single</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">converged</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">max_conds_dim</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Print statement about the convergence of the pc_stable_single algorithm.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        convergence : bool</span>
<span class="sd">            true if convergence was reached.</span>
<span class="sd">        j : int</span>
<span class="sd">            Variable index.</span>
<span class="sd">        max_conds_dim : int</span>
<span class="sd">            Maximum number of conditions to test.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">converged</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Algorithm converged for variable </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                  <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span>
                <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Algorithm not yet converged, but max_conds_dim = </span><span class="si">%d</span><span class="s2">&quot;</span>
                <span class="s2">&quot; reached.&quot;</span> <span class="o">%</span> <span class="n">max_conds_dim</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_run_pc_stable_single</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span>
                              <span class="n">link_assumptions_j</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                              <span class="n">tau_min</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                              <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                              <span class="n">save_iterations</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                              <span class="n">pc_alpha</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span>
                              <span class="n">max_conds_dim</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                              <span class="n">max_combinations</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Lagged PC algorithm for estimating lagged parents of single variable.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        j : int</span>
<span class="sd">            Variable index.</span>
<span class="sd">        link_assumptions_j : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, optional (default: 1)</span>
<span class="sd">            Minimum time lag to test. Useful for variable selection in</span>
<span class="sd">            multi-step ahead predictions. Must be greater zero.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        save_iterations : bool, optional (default: False)</span>
<span class="sd">            Whether to save iteration step results such as conditions used.</span>
<span class="sd">        pc_alpha : float or None, optional (default: 0.2)</span>
<span class="sd">            Significance level in algorithm. If a list is given, pc_alpha is</span>
<span class="sd">            optimized using model selection criteria provided in the</span>
<span class="sd">            cond_ind_test class as get_model_selection_criterion(). If None,</span>
<span class="sd">            a default list of values is used.</span>
<span class="sd">        max_conds_dim : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int, optional (default: 1)</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test in PC1 step.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        parents : list</span>
<span class="sd">            List of estimated parents.</span>
<span class="sd">        val_min : dict</span>
<span class="sd">            Dictionary of form {(0, -1):float, ...} containing the minimum test</span>
<span class="sd">            statistic value of a link.</span>
<span class="sd">        pval_max : dict</span>
<span class="sd">            Dictionary of form {(0, -1):float, ...} containing the maximum</span>
<span class="sd">            p-value of a link across different conditions.</span>
<span class="sd">        iterations : dict</span>
<span class="sd">            Dictionary containing further information on algorithm steps.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">pc_alpha</span> <span class="o">&lt;</span> <span class="mf">0.</span> <span class="ow">or</span> <span class="n">pc_alpha</span> <span class="o">&gt;</span> <span class="mf">1.</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Choose 0 &lt;= pc_alpha &lt;= 1&quot;</span><span class="p">)</span>

        <span class="c1"># Initialize the dictionaries for the pval_max, val_min parents_values</span>
        <span class="c1"># results</span>
        <span class="n">pval_max</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="n">val_min</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="n">parents_values</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="c1"># Initialize the parents values from the selected links, copying to</span>
        <span class="c1"># ensure this initial argument is unchanged.</span>
        <span class="n">parents</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">itau</span> <span class="ow">in</span> <span class="n">link_assumptions_j</span><span class="p">:</span>
            <span class="n">link_type</span> <span class="o">=</span> <span class="n">link_assumptions_j</span><span class="p">[</span><span class="n">itau</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">itau</span> <span class="o">!=</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="n">link_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;&lt;--&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;?-&#39;</span><span class="p">]:</span>
                <span class="n">parents</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itau</span><span class="p">)</span>

        <span class="n">val_min</span> <span class="o">=</span> <span class="p">{(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> <span class="kc">None</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parents</span><span class="p">}</span>
        <span class="n">pval_max</span> <span class="o">=</span> <span class="p">{(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> <span class="kc">None</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parents</span><span class="p">}</span>

        <span class="c1"># Define a nested defaultdict of depth 4 to save all information about</span>
        <span class="c1"># iterations</span>
        <span class="n">iterations</span> <span class="o">=</span> <span class="n">_create_nested_dictionary</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
        <span class="c1"># Ensure tau_min is at least 1</span>
        <span class="n">tau_min</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">)</span>

        <span class="c1"># Loop over all possible condition dimensions</span>
        <span class="n">max_conds_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_dim</span><span class="p">,</span>
                                                    <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="c1"># Iteration through increasing number of conditions, i.e. from </span>
        <span class="c1"># [0, max_conds_dim] inclusive</span>
        <span class="n">converged</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="k">for</span> <span class="n">conds_dim</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_conds_dim</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
            <span class="c1"># (Re)initialize the list of non-significant links</span>
            <span class="n">nonsig_parents</span> <span class="o">=</span> <span class="nb">list</span><span class="p">()</span>
            <span class="c1"># Check if the algorithm has converged</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parents</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&lt;</span> <span class="n">conds_dim</span><span class="p">:</span>
                <span class="n">converged</span> <span class="o">=</span> <span class="kc">True</span>
                <span class="k">break</span>
            <span class="c1"># Print information about</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Testing condition sets of dimension </span><span class="si">%d</span><span class="s2">:&quot;</span> <span class="o">%</span> <span class="n">conds_dim</span><span class="p">)</span>

            <span class="c1"># Iterate through all possible pairs (that have not converged yet)</span>
            <span class="k">for</span> <span class="n">index_parent</span><span class="p">,</span> <span class="n">parent</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">parents</span><span class="p">):</span>
                <span class="c1"># Print info about this link</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_print_link_info</span><span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">index_parent</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">parents</span><span class="p">))</span>
                <span class="c1"># Iterate through all possible combinations</span>
                <span class="n">nonsig</span> <span class="o">=</span> <span class="kc">False</span>
                <span class="k">for</span> <span class="n">comb_index</span><span class="p">,</span> <span class="n">Z</span> <span class="ow">in</span> \
                        <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_iter_conditions</span><span class="p">(</span><span class="n">parent</span><span class="p">,</span> <span class="n">conds_dim</span><span class="p">,</span>
                                                        <span class="n">parents</span><span class="p">)):</span>
                    <span class="c1"># Break if we try too many combinations</span>
                    <span class="k">if</span> <span class="n">comb_index</span> <span class="o">&gt;=</span> <span class="n">max_combinations</span><span class="p">:</span>
                        <span class="k">break</span>
                    <span class="c1"># Perform independence test</span>
                    <span class="k">if</span> <span class="n">link_assumptions_j</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;--&gt;&#39;</span><span class="p">:</span>
                        <span class="n">val</span> <span class="o">=</span> <span class="mf">1.</span>
                        <span class="n">pval</span> <span class="o">=</span> <span class="mf">0.</span>
                        <span class="n">dependent</span> <span class="o">=</span> <span class="kc">True</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">dependent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">run_test</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[</span><span class="n">parent</span><span class="p">],</span>
                                                    <span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span>
                                                    <span class="n">Z</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span>
                                                    <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                                                    <span class="n">alpha_or_thres</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
                                                    <span class="p">)</span>
                    <span class="c1"># Print some information if needed</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">_print_cond_info</span><span class="p">(</span><span class="n">Z</span><span class="p">,</span> <span class="n">comb_index</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
                    <span class="c1"># Keep track of maximum p-value and minimum estimated value</span>
                    <span class="c1"># for each pair (across any condition)</span>
                    <span class="n">parents_values</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span> <span class="o">=</span> \
                        <span class="nb">min</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val</span><span class="p">),</span> <span class="n">parents_values</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">parent</span><span class="p">,</span>
                                                            <span class="nb">float</span><span class="p">(</span><span class="s2">&quot;inf&quot;</span><span class="p">)))</span>

                    <span class="k">if</span> <span class="n">pval_max</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">pval</span> <span class="o">&gt;</span> <span class="n">pval_max</span><span class="p">[</span><span class="n">parent</span><span class="p">]:</span>
                        <span class="n">pval_max</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span> <span class="o">=</span> <span class="n">pval</span>
                        <span class="n">val_min</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span>

                    <span class="c1"># Save the iteration if we need to</span>
                    <span class="k">if</span> <span class="n">save_iterations</span><span class="p">:</span>
                        <span class="n">a_iter</span> <span class="o">=</span> <span class="n">iterations</span><span class="p">[</span><span class="s1">&#39;iterations&#39;</span><span class="p">][</span><span class="n">conds_dim</span><span class="p">][</span><span class="n">parent</span><span class="p">]</span>
                        <span class="n">a_iter</span><span class="p">[</span><span class="n">comb_index</span><span class="p">][</span><span class="s1">&#39;conds&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">Z</span><span class="p">)</span>
                        <span class="n">a_iter</span><span class="p">[</span><span class="n">comb_index</span><span class="p">][</span><span class="s1">&#39;val&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span>
                        <span class="n">a_iter</span><span class="p">[</span><span class="n">comb_index</span><span class="p">][</span><span class="s1">&#39;pval&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">pval</span>
                    <span class="c1"># Delete link later and break while-loop if non-significant</span>
                    <span class="k">if</span> <span class="ow">not</span> <span class="n">dependent</span><span class="p">:</span> <span class="c1">#pval &gt; pc_alpha:</span>
                        <span class="n">nonsig_parents</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="n">parent</span><span class="p">))</span>
                        <span class="n">nonsig</span> <span class="o">=</span> <span class="kc">True</span>
                        <span class="k">break</span>

                <span class="c1"># Print the results if needed</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_print_a_pc_result</span><span class="p">(</span><span class="n">nonsig</span><span class="p">,</span>
                                            <span class="n">conds_dim</span><span class="p">,</span> <span class="n">max_combinations</span><span class="p">)</span>

            <span class="c1"># Remove non-significant links</span>
            <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">parent</span> <span class="ow">in</span> <span class="n">nonsig_parents</span><span class="p">:</span>
                <span class="k">del</span> <span class="n">parents_values</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span>
            <span class="c1"># Return the parents list sorted by the test metric so that the</span>
            <span class="c1"># updated parents list is given to the next cond_dim loop</span>
            <span class="n">parents</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sort_parents</span><span class="p">(</span><span class="n">parents_values</span><span class="p">)</span>
            <span class="c1"># Print information about the change in possible parents</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Updating parents:&quot;</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents_single</span><span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">parents</span><span class="p">,</span> <span class="n">parents_values</span><span class="p">,</span> <span class="n">pval_max</span><span class="p">)</span>

        <span class="c1"># Print information about if convergence was reached</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_print_converged_pc_single</span><span class="p">(</span><span class="n">converged</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">max_conds_dim</span><span class="p">)</span>
        <span class="c1"># Return the results</span>
        <span class="k">return</span> <span class="p">{</span><span class="s1">&#39;parents&#39;</span><span class="p">:</span> <span class="n">parents</span><span class="p">,</span>
                <span class="s1">&#39;val_min&#39;</span><span class="p">:</span> <span class="n">val_min</span><span class="p">,</span>
                <span class="s1">&#39;pval_max&#39;</span><span class="p">:</span> <span class="n">pval_max</span><span class="p">,</span>
                <span class="s1">&#39;iterations&#39;</span><span class="p">:</span> <span class="n">_nested_to_normal</span><span class="p">(</span><span class="n">iterations</span><span class="p">)}</span>

    <span class="k">def</span> <span class="nf">_print_pc_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">link_assumptions</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">pc_alpha</span><span class="p">,</span>
                         <span class="n">max_conds_dim</span><span class="p">,</span> <span class="n">max_combinations</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print the setup of the current pc_stable run.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        link_assumptions : dict or None</span>
<span class="sd">            Dictionary of form specifying which links should be tested.</span>
<span class="sd">        tau_min : int, default: 1</span>
<span class="sd">            Minimum time lag to test.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag to test.</span>
<span class="sd">        pc_alpha : float or list of floats</span>
<span class="sd">            Significance level in algorithm.</span>
<span class="sd">        max_conds_dim : int</span>
<span class="sd">            Maximum number of conditions to test.</span>
<span class="sd">        max_combinations : int</span>
<span class="sd">            Maximum number of combinations of conditions to test.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Step 1: PC1 algorithm for selecting lagged conditions</span><span class="se">\n</span><span class="s2">##&quot;</span>
              <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">Parameters:&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">link_assumptions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;link_assumptions = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">))</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;independence test = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">measure</span>
              <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_min = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_min</span>
              <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_max = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_max</span>
              <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">pc_alpha = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pc_alpha</span>
              <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_dim = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_dim</span>
              <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_combinations = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_combinations</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_print_pc_sel_results</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pc_alpha</span><span class="p">,</span> <span class="n">results</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">score</span><span class="p">,</span> <span class="n">optimal_alpha</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print the results from the pc_alpha selection.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        pc_alpha : list</span>
<span class="sd">            Tested significance levels in algorithm.</span>
<span class="sd">        results : dict</span>
<span class="sd">            Results from the tested pc_alphas.</span>
<span class="sd">        score : array of floats</span>
<span class="sd">            scores from each pc_alpha.</span>
<span class="sd">        j : int</span>
<span class="sd">            Index of current variable.</span>
<span class="sd">        optimal_alpha : float</span>
<span class="sd">            Optimal value of pc_alpha.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2"># Condition selection results:&quot;</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">iscore</span><span class="p">,</span> <span class="n">pc_alpha_here</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">pc_alpha</span><span class="p">):</span>
            <span class="n">names_parents</span> <span class="o">=</span> <span class="s2">&quot;[ &quot;</span>
            <span class="k">for</span> <span class="n">pari</span> <span class="ow">in</span> <span class="n">results</span><span class="p">[</span><span class="n">pc_alpha_here</span><span class="p">][</span><span class="s1">&#39;parents&#39;</span><span class="p">]:</span>
                <span class="n">names_parents</span> <span class="o">+=</span> <span class="s2">&quot;(</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) &quot;</span> <span class="o">%</span> <span class="p">(</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">pari</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">pari</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
            <span class="n">names_parents</span> <span class="o">+=</span> <span class="s2">&quot;]&quot;</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;    pc_alpha=</span><span class="si">%s</span><span class="s2"> got score </span><span class="si">%.4f</span><span class="s2"> with parents </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
                  <span class="p">(</span><span class="n">pc_alpha_here</span><span class="p">,</span> <span class="n">score</span><span class="p">[</span><span class="n">iscore</span><span class="p">],</span> <span class="n">names_parents</span><span class="p">))</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">==&gt; optimal pc_alpha for variable </span><span class="si">%s</span><span class="s2"> is </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span>
              <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">optimal_alpha</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">_check_tau_limits</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Check the tau limits adhere to 0 &lt;= tau_min &lt;= tau_max.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        tau_min : float</span>
<span class="sd">            Minimum tau value.</span>
<span class="sd">        tau_max : float</span>
<span class="sd">            Maximum tau value.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">tau_min</span> <span class="o">&lt;=</span> <span class="n">tau_max</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;tau_max = </span><span class="si">%d</span><span class="s2">, &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">tau_max</span><span class="p">)</span> <span class="o">+</span> \
                             <span class="s2">&quot;tau_min = </span><span class="si">%d</span><span class="s2">, &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">tau_min</span><span class="p">)</span> <span class="o">+</span> \
                             <span class="s2">&quot;but 0 &lt;= tau_min &lt;= tau_max&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_set_max_condition_dim</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">max_conds_dim</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the maximum dimension of the conditions. Defaults to self.N*tau_max.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        max_conds_dim : int</span>
<span class="sd">            Input maximum condition dimension.</span>
<span class="sd">        tau_max : int</span>
<span class="sd">            Maximum tau.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        max_conds_dim : int</span>
<span class="sd">            Input maximum condition dimension or default.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Check if an input was given</span>
        <span class="k">if</span> <span class="n">max_conds_dim</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">max_conds_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span> <span class="o">*</span> <span class="p">(</span><span class="n">tau_max</span> <span class="o">-</span> <span class="n">tau_min</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
        <span class="c1"># Check this is a valid</span>
        <span class="k">if</span> <span class="n">max_conds_dim</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;maximum condition dimension must be &gt;= 0&quot;</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">max_conds_dim</span>

<div class="viewcode-block" id="PCMCI.run_pc_stable"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_pc_stable">[docs]</a>    <span class="k">def</span> <span class="nf">run_pc_stable</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                      <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">tau_min</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                      <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                      <span class="n">save_iterations</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                      <span class="n">pc_alpha</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span>
                      <span class="n">max_conds_dim</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">max_combinations</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Lagged PC algorithm for estimating lagged parents of all variables.</span>

<span class="sd">        Parents are made available as self.all_parents</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, default: 1</span>
<span class="sd">            Minimum time lag to test. Useful for multi-step ahead predictions.</span>
<span class="sd">            Must be greater zero.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        save_iterations : bool, default: False</span>
<span class="sd">            Whether to save iteration step results such as conditions used.</span>
<span class="sd">        pc_alpha : float or list of floats, default: [0.05, 0.1, 0.2, ..., 0.5]</span>
<span class="sd">            Significance level in algorithm. If a list or None is passed, the</span>
<span class="sd">            pc_alpha level is optimized for every variable across the given</span>
<span class="sd">            pc_alpha values using the score computed in</span>
<span class="sd">            cond_ind_test.get_model_selection_criterion().</span>
<span class="sd">        max_conds_dim : int or None</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int, default: 1</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test in PC1 step.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        all_parents : dict</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...}</span>
<span class="sd">            containing estimated parents.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>

        <span class="c1"># Create an internal copy of pc_alpha</span>
        <span class="n">_int_pc_alpha</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">pc_alpha</span><span class="p">)</span>
        <span class="c1"># Check if we are selecting an optimal alpha value</span>
        <span class="n">select_optimal_alpha</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="c1"># Set the default values for pc_alpha</span>
        <span class="k">if</span> <span class="n">_int_pc_alpha</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">_int_pc_alpha</span> <span class="o">=</span> <span class="p">[</span><span class="mf">0.05</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.4</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">]</span>
        <span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">_int_pc_alpha</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">)):</span>
            <span class="n">_int_pc_alpha</span> <span class="o">=</span> <span class="p">[</span><span class="n">_int_pc_alpha</span><span class="p">]</span>
            <span class="n">select_optimal_alpha</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="c1"># Check the limits on tau_min</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_check_tau_limits</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="n">tau_min</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">)</span>
        <span class="c1"># Check that the maximum combinations variable is correct</span>
        <span class="k">if</span> <span class="n">max_combinations</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;max_combinations must be &gt; 0&quot;</span><span class="p">)</span>
        <span class="c1"># Implement defaultdict for all pval_max, val_max, and iterations</span>
        <span class="n">pval_max</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span>
        <span class="n">val_min</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span>
        <span class="n">iterations</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_print_pc_params</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span>
                              <span class="n">_int_pc_alpha</span><span class="p">,</span> <span class="n">max_conds_dim</span><span class="p">,</span>
                              <span class="n">max_combinations</span><span class="p">)</span>

        <span class="c1"># Set the selected links</span>
        <span class="c1"># _int_sel_links = self._set_sel_links(selected_links, tau_min, tau_max,</span>
        <span class="c1">#                                      remove_contemp=True)</span>
        <span class="n">_int_link_assumptions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_link_assumptions</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">,</span> 
            <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">remove_contemp</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

        <span class="c1"># Initialize all parents</span>
        <span class="n">all_parents</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="c1"># Set the maximum condition dimension</span>
        <span class="n">max_conds_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_dim</span><span class="p">,</span>
                                                    <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="c1"># Loop through the selected variables</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="c1"># Print the status of this variable</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">## Variable </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Iterating through pc_alpha = </span><span class="si">%s</span><span class="s2">:&quot;</span> <span class="o">%</span> <span class="n">_int_pc_alpha</span><span class="p">)</span>
            <span class="c1"># Initialize the scores for selecting the optimal alpha</span>
            <span class="n">score</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">_int_pc_alpha</span><span class="p">)</span>
            <span class="c1"># Initialize the result</span>
            <span class="n">results</span> <span class="o">=</span> <span class="p">{}</span>
            <span class="k">for</span> <span class="n">iscore</span><span class="p">,</span> <span class="n">pc_alpha_here</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">_int_pc_alpha</span><span class="p">):</span>
                <span class="c1"># Print statement about the pc_alpha being tested</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2"># pc_alpha = </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%d</span><span class="s2">/</span><span class="si">%d</span><span class="s2">):&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pc_alpha_here</span><span class="p">,</span>
                                                          <span class="n">iscore</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
                                                          <span class="n">score</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
                <span class="c1"># Get the results for this alpha value</span>
                <span class="n">results</span><span class="p">[</span><span class="n">pc_alpha_here</span><span class="p">]</span> <span class="o">=</span> \
                    <span class="bp">self</span><span class="o">.</span><span class="n">_run_pc_stable_single</span><span class="p">(</span><span class="n">j</span><span class="p">,</span>
                                               <span class="n">link_assumptions_j</span><span class="o">=</span><span class="n">_int_link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                               <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
                                               <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                                               <span class="n">save_iterations</span><span class="o">=</span><span class="n">save_iterations</span><span class="p">,</span>
                                               <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha_here</span><span class="p">,</span>
                                               <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
                                               <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">)</span>
                <span class="c1"># Figure out the best score if there is more than one pc_alpha</span>
                <span class="c1"># value</span>
                <span class="k">if</span> <span class="n">select_optimal_alpha</span><span class="p">:</span>
                    <span class="n">score</span><span class="p">[</span><span class="n">iscore</span><span class="p">]</span> <span class="o">=</span> \
                        <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">get_model_selection_criterion</span><span class="p">(</span>
                            <span class="n">j</span><span class="p">,</span> <span class="n">results</span><span class="p">[</span><span class="n">pc_alpha_here</span><span class="p">][</span><span class="s1">&#39;parents&#39;</span><span class="p">],</span> <span class="n">tau_max</span><span class="p">)</span>
            <span class="c1"># Record the optimal alpha value</span>
            <span class="n">optimal_alpha</span> <span class="o">=</span> <span class="n">_int_pc_alpha</span><span class="p">[</span><span class="n">score</span><span class="o">.</span><span class="n">argmin</span><span class="p">()]</span>
            <span class="c1"># Only print the selection results if there is more than one</span>
            <span class="c1"># pc_alpha</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">select_optimal_alpha</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_print_pc_sel_results</span><span class="p">(</span><span class="n">_int_pc_alpha</span><span class="p">,</span> <span class="n">results</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span>
                                           <span class="n">score</span><span class="p">,</span> <span class="n">optimal_alpha</span><span class="p">)</span>
            <span class="c1"># Record the results for this variable</span>
            <span class="n">all_parents</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="n">optimal_alpha</span><span class="p">][</span><span class="s1">&#39;parents&#39;</span><span class="p">]</span>
            <span class="n">val_min</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="n">optimal_alpha</span><span class="p">][</span><span class="s1">&#39;val_min&#39;</span><span class="p">]</span>
            <span class="n">pval_max</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="n">optimal_alpha</span><span class="p">][</span><span class="s1">&#39;pval_max&#39;</span><span class="p">]</span>
            <span class="n">iterations</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="n">optimal_alpha</span><span class="p">][</span><span class="s1">&#39;iterations&#39;</span><span class="p">]</span>
            <span class="c1"># Only save the optimal alpha if there is more than one pc_alpha</span>
            <span class="k">if</span> <span class="n">select_optimal_alpha</span><span class="p">:</span>
                <span class="n">iterations</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="s1">&#39;optimal_pc_alpha&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">optimal_alpha</span>
        <span class="c1"># Save the results in the current status of the algorithm</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">all_parents</span> <span class="o">=</span> <span class="n">all_parents</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">val_matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dict_to_matrix</span><span class="p">(</span><span class="n">val_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> 
                                               <span class="n">default</span><span class="o">=</span><span class="mf">0.</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">p_matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dict_to_matrix</span><span class="p">(</span><span class="n">pval_max</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span>
                                            <span class="n">default</span><span class="o">=</span><span class="mf">1.</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">iterations</span> <span class="o">=</span> <span class="n">iterations</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">val_min</span> <span class="o">=</span> <span class="n">val_min</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">pval_max</span> <span class="o">=</span> <span class="n">pval_max</span>
        <span class="c1"># Print the results</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">## Resulting lagged parent (super)sets:&quot;</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents</span><span class="p">(</span><span class="n">all_parents</span><span class="p">,</span> <span class="n">val_min</span><span class="p">,</span> <span class="n">pval_max</span><span class="p">)</span>
        <span class="c1"># Return the parents</span>
        <span class="k">return</span> <span class="n">all_parents</span></div>

    <span class="k">def</span> <span class="nf">_print_parents_single</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">parents</span><span class="p">,</span> <span class="n">val_min</span><span class="p">,</span> <span class="n">pval_max</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print current parents for variable j.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        j : int</span>
<span class="sd">            Index of current variable.</span>
<span class="sd">        parents : list</span>
<span class="sd">            List of form [(0, -1), (3, -2), ...].</span>
<span class="sd">        val_min : dict</span>
<span class="sd">            Dictionary of form {(0, -1):float, ...} containing the minimum test</span>
<span class="sd">            statistic value of a link.</span>
<span class="sd">        pval_max : dict</span>
<span class="sd">            Dictionary of form {(0, -1):float, ...} containing the maximum</span>
<span class="sd">            p-value of a link across different conditions.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parents</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">20</span> <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;iterations&#39;</span><span class="p">):</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Variable </span><span class="si">%s</span><span class="s2"> has </span><span class="si">%d</span><span class="s2"> link(s):&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="nb">len</span><span class="p">(</span><span class="n">parents</span><span class="p">)))</span>
            <span class="k">if</span> <span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;iterations&#39;</span><span class="p">)</span>
                    <span class="ow">and</span> <span class="s1">&#39;optimal_pc_alpha&#39;</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">iterations</span><span class="p">[</span><span class="n">j</span><span class="p">])):</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;    [pc_alpha = </span><span class="si">%s</span><span class="s2">]&quot;</span> <span class="o">%</span> <span class="p">(</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">iterations</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="s1">&#39;optimal_pc_alpha&#39;</span><span class="p">]))</span>
            <span class="k">if</span> <span class="n">val_min</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">pval_max</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parents</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;        (</span><span class="si">%s</span><span class="s2"> % .d)&quot;</span> <span class="o">%</span> <span class="p">(</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">parents</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;        (</span><span class="si">%s</span><span class="s2"> % .d): max_pval = </span><span class="si">%.5f</span><span class="s2">, min_val = </span><span class="si">% .3f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">pval_max</span><span class="p">[</span><span class="n">p</span><span class="p">],</span>
                        <span class="n">val_min</span><span class="p">[</span><span class="n">p</span><span class="p">]))</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Variable </span><span class="si">%s</span><span class="s2"> has </span><span class="si">%d</span><span class="s2"> link(s):&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="nb">len</span><span class="p">(</span><span class="n">parents</span><span class="p">)))</span>

    <span class="k">def</span> <span class="nf">_print_parents</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">all_parents</span><span class="p">,</span> <span class="n">val_min</span><span class="p">,</span> <span class="n">pval_max</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print current parents.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        all_parents : dictionary</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...} containing</span>
<span class="sd">            the conditioning-parents estimated with PC algorithm.</span>
<span class="sd">        val_min : dict</span>
<span class="sd">            Dictionary of form {0:{(0, -1):float, ...}} containing the minimum</span>
<span class="sd">            test statistic value of a link.</span>
<span class="sd">        pval_max : dict</span>
<span class="sd">            Dictionary of form {0:{(0, -1):float, ...}} containing the maximum</span>
<span class="sd">            p-value of a link across different conditions.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="p">[</span><span class="n">var</span> <span class="k">for</span> <span class="n">var</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">all_parents</span><span class="p">)]:</span>
            <span class="k">if</span> <span class="n">val_min</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">pval_max</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents_single</span><span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">all_parents</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                           <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents_single</span><span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">all_parents</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                           <span class="n">val_min</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">pval_max</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>

    <span class="k">def</span> <span class="nf">_mci_condition_to_string</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conds</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Convert the list of conditions into a string.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        conds : list</span>
<span class="sd">            List of conditions.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">cond_string</span> <span class="o">=</span> <span class="s2">&quot;[ &quot;</span>
        <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">tau_k</span> <span class="ow">in</span> <span class="n">conds</span><span class="p">:</span>
            <span class="n">cond_string</span> <span class="o">+=</span> <span class="s2">&quot;(</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span> <span class="n">tau_k</span><span class="p">)</span>
        <span class="n">cond_string</span> <span class="o">+=</span> <span class="s2">&quot;]&quot;</span>
        <span class="k">return</span> <span class="n">cond_string</span>

    <span class="k">def</span> <span class="nf">_print_mci_conditions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conds_y</span><span class="p">,</span> <span class="n">conds_x_lagged</span><span class="p">,</span>
                              <span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">n_parents</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print information about the conditions for the MCI algorithm.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        conds_y : list</span>
<span class="sd">            Conditions on node.</span>
<span class="sd">        conds_x_lagged : list</span>
<span class="sd">            Conditions on parent.</span>
<span class="sd">        j : int</span>
<span class="sd">            Current node.</span>
<span class="sd">        i : int</span>
<span class="sd">            Parent node.</span>
<span class="sd">        tau : int</span>
<span class="sd">            Parent time delay.</span>
<span class="sd">        count : int</span>
<span class="sd">            Index of current parent.</span>
<span class="sd">        n_parents : int</span>
<span class="sd">            Total number of parents.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Remove the current parent from the conditions</span>
        <span class="n">conds_y_no_i</span> <span class="o">=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">conds_y</span> <span class="k">if</span> <span class="n">node</span> <span class="o">!=</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">)]</span>
        <span class="c1"># Get the condition string for parent</span>
        <span class="n">condy_str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mci_condition_to_string</span><span class="p">(</span><span class="n">conds_y_no_i</span><span class="p">)</span>
        <span class="c1"># Get the condition string for node</span>
        <span class="n">condx_str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mci_condition_to_string</span><span class="p">(</span><span class="n">conds_x_lagged</span><span class="p">)</span>
        <span class="c1"># Formate and print the information</span>
        <span class="n">link_marker</span> <span class="o">=</span> <span class="p">{</span><span class="kc">True</span><span class="p">:</span><span class="s2">&quot;o?o&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span><span class="s2">&quot;-?&gt;&quot;</span><span class="p">}</span>
        <span class="n">indent</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">        &quot;</span>
        <span class="n">print_str</span> <span class="o">=</span> <span class="n">indent</span> <span class="o">+</span> <span class="s2">&quot;link (</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">tau</span><span class="p">)</span>
        <span class="n">print_str</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%d</span><span class="s2">/</span><span class="si">%d</span><span class="s2">):&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">link_marker</span><span class="p">[</span><span class="n">tau</span><span class="o">==</span><span class="mi">0</span><span class="p">],</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n_parents</span><span class="p">)</span>
        <span class="n">print_str</span> <span class="o">+=</span> <span class="n">indent</span> <span class="o">+</span> <span class="s2">&quot;with conds_y = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">condy_str</span><span class="p">)</span>
        <span class="n">print_str</span> <span class="o">+=</span> <span class="n">indent</span> <span class="o">+</span> <span class="s2">&quot;with conds_x = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">condx_str</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">print_str</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_print_pcmciplus_conditions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lagged_parents</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">,</span>
                                    <span class="n">max_conds_py</span><span class="p">,</span> <span class="n">max_conds_px</span><span class="p">,</span> 
                                    <span class="n">max_conds_px_lagged</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print information about the conditions for PCMCIplus.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        lagged_parents : dictionary of lists</span>
<span class="sd">            Dictionary of lagged parents for each node.</span>
<span class="sd">        j : int</span>
<span class="sd">            Current node.</span>
<span class="sd">        i : int</span>
<span class="sd">            Parent node.</span>
<span class="sd">        abstau : int</span>
<span class="sd">            Parent time delay.</span>
<span class="sd">        max_conds_py : int</span>
<span class="sd">            Max number of parents for node j.</span>
<span class="sd">        max_conds_px : int</span>
<span class="sd">            Max number of parents for lagged node i.</span>
<span class="sd">        max_conds_px_lagged : int</span>
<span class="sd">            Maximum number of lagged conditions of X when X is lagged in MCI </span>
<span class="sd">            tests. If None is passed, this number is equal to max_conds_px.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">conds_y</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">j</span><span class="p">][:</span><span class="n">max_conds_py</span><span class="p">]</span>
        <span class="n">conds_y_no_i</span> <span class="o">=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">conds_y</span> <span class="k">if</span> <span class="n">node</span> <span class="o">!=</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)]</span>
        <span class="k">if</span> <span class="n">abstau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">conds_x</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">max_conds_px_lagged</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">conds_x</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px</span><span class="p">]</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">conds_x</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px_lagged</span><span class="p">]</span>

        <span class="c1"># Shift the conditions for X by tau</span>
        <span class="n">conds_x_lagged</span> <span class="o">=</span> <span class="p">[(</span><span class="n">k</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span> <span class="o">+</span> <span class="n">k_tau</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">k_tau</span> <span class="ow">in</span> <span class="n">conds_x</span><span class="p">]</span>
        <span class="n">condy_str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mci_condition_to_string</span><span class="p">(</span><span class="n">conds_y_no_i</span><span class="p">)</span>
        <span class="n">condx_str</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mci_condition_to_string</span><span class="p">(</span><span class="n">conds_x_lagged</span><span class="p">)</span>
        <span class="n">print_str</span> <span class="o">=</span> <span class="s2">&quot;    with conds_y = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">condy_str</span><span class="p">)</span>
        <span class="n">print_str</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    with conds_x = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">condx_str</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">print_str</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_get_int_parents</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parents</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Get the input parents dictionary.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        parents : dict or None</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...}</span>
<span class="sd">            specifying the conditions for each variable. If None is</span>
<span class="sd">            passed, no conditions are used.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        int_parents : defaultdict of lists</span>
<span class="sd">            Internal copy of parents, respecting default options</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">int_parents</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">parents</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">int_parents</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">int_parents</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">int_parents</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="n">int_parents</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">int_parents</span>

    <span class="k">def</span> <span class="nf">_iter_indep_conds</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                          <span class="n">parents</span><span class="p">,</span>
                          <span class="n">_int_link_assumptions</span><span class="p">,</span>
                          <span class="n">max_conds_py</span><span class="p">,</span>
                          <span class="n">max_conds_px</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Iterate through the conditions dictated by the arguments, yielding</span>
<span class="sd">        the needed arguments for conditional independence functions.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        parents : dict</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...}</span>
<span class="sd">            specifying the conditions for each variable.</span>
<span class="sd">        _int_link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        max_conds_py : int</span>
<span class="sd">            Maximum number of conditions of Y to use.</span>
<span class="sd">        max_conds_px : int</span>
<span class="sd">            Maximum number of conditions of Z to use.</span>

<span class="sd">        Yields</span>
<span class="sd">        ------</span>
<span class="sd">        i, j, tau, Z : list of tuples</span>
<span class="sd">            (i, tau) is the parent node, (j, 0) is the current node, and Z is of</span>
<span class="sd">            the form [(var, tau + tau&#39;)] and specifies the condition to test</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Loop over the selected variables</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="c1"># Get the conditions for node j</span>
            <span class="n">conds_y</span> <span class="o">=</span> <span class="n">parents</span><span class="p">[</span><span class="n">j</span><span class="p">][:</span><span class="n">max_conds_py</span><span class="p">]</span>
            <span class="c1"># Create a parent list from links seperated in time and by node</span>
            <span class="c1"># parent_list = [(i, tau) for i, tau in _int_link_assumptions[j]</span>
            <span class="c1">#                if (i, tau) != (j, 0)]</span>
            <span class="n">parent_list</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">itau</span> <span class="ow">in</span> <span class="n">_int_link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="n">link_type</span> <span class="o">=</span> <span class="n">_int_link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">itau</span><span class="p">]</span>
                <span class="k">if</span> <span class="n">itau</span> <span class="o">!=</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="n">link_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;&lt;--&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;?-&#39;</span><span class="p">]:</span>
                    <span class="n">parent_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itau</span><span class="p">)</span>
            <span class="c1"># Iterate through parents (except those in conditions)</span>
            <span class="k">for</span> <span class="n">cnt</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">parent_list</span><span class="p">):</span>
                <span class="c1"># Get the conditions for node i</span>
                <span class="n">conds_x</span> <span class="o">=</span> <span class="n">parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px</span><span class="p">]</span>
                <span class="c1"># Shift the conditions for X by tau</span>
                <span class="n">conds_x_lagged</span> <span class="o">=</span> <span class="p">[(</span><span class="n">k</span><span class="p">,</span> <span class="n">tau</span> <span class="o">+</span> <span class="n">k_tau</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">k_tau</span> <span class="ow">in</span> <span class="n">conds_x</span><span class="p">]</span>
                <span class="c1"># Print information about the mci conditions if requested</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_print_mci_conditions</span><span class="p">(</span><span class="n">conds_y</span><span class="p">,</span> <span class="n">conds_x_lagged</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span>
                                               <span class="n">tau</span><span class="p">,</span> <span class="n">cnt</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">parent_list</span><span class="p">))</span>
                <span class="c1"># Construct lists of tuples for estimating</span>
                <span class="c1"># I(X_t-tau; Y_t | Z^Y_t, Z^X_t-tau)</span>
                <span class="c1"># with conditions for X shifted by tau</span>
                <span class="n">Z</span> <span class="o">=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">conds_y</span> <span class="k">if</span> <span class="n">node</span> <span class="o">!=</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">)]</span>
                <span class="c1"># Remove overlapped nodes between conds_x_lagged and conds_y</span>
                <span class="n">Z</span> <span class="o">+=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">conds_x_lagged</span> <span class="k">if</span> <span class="n">node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">]</span>
                <span class="c1"># Yield these list</span>
                <span class="k">yield</span> <span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">,</span> <span class="n">Z</span>

    <span class="k">def</span> <span class="nf">_run_mci_or_variants</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                             <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                             <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                             <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                             <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                             <span class="n">parents</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                             <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                             <span class="n">max_conds_px</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                             <span class="n">val_only</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                             <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                             <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Base function for MCI method and variants.</span>

<span class="sd">        Returns the matrices of test statistic values, (optionally corrected) </span>
<span class="sd">        p-values, and (optionally) confidence intervals. Also (new in 4.3)</span>
<span class="sd">        returns graph based on alpha_level (and optional FDR-correction).</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, default: 0</span>
<span class="sd">            Minimum time lag to test. Note that zero-lags are undirected.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        parents : dict or None</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...}</span>
<span class="sd">            specifying the conditions for each variable. If None is</span>
<span class="sd">            passed, no conditions are used.</span>
<span class="sd">        max_conds_py : int or None</span>
<span class="sd">            Maximum number of conditions of Y to use. If None is passed, this</span>
<span class="sd">            number is unrestricted.</span>
<span class="sd">        max_conds_px : int or None</span>
<span class="sd">            Maximum number of conditions of Z to use. If None is passed, this</span>
<span class="sd">            number is unrestricted.</span>
<span class="sd">        val_only : bool, default: False</span>
<span class="sd">            Option to only compute dependencies and not p-values.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;none&#39;)</span>
<span class="sd">            Correction method, currently implemented is Benjamini-Hochberg</span>
<span class="sd">            False Discovery Rate method (&#39;fdr_bh&#39;). </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        conf_matrix : array of shape [N, N, tau_max+1,2]</span>
<span class="sd">            Estimated matrix of confidence intervals of test statistic values.</span>
<span class="sd">            Only computed if set in cond_ind_test, where also the percentiles</span>
<span class="sd">            are set.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>

        <span class="c1"># Check the limits on tau</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_check_tau_limits</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="c1"># Set the selected links</span>
        <span class="c1"># _int_sel_links = self._set_sel_links(selected_links, tau_min, tau_max)</span>
        <span class="n">_int_link_assumptions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_link_assumptions</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="c1"># Set the maximum condition dimension for Y and X</span>
        <span class="n">max_conds_py</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_py</span><span class="p">,</span>
                                                   <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="n">max_conds_px</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_px</span><span class="p">,</span>
                                                   <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="c1"># Get the parents that will be checked</span>
        <span class="n">_int_parents</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_int_parents</span><span class="p">(</span><span class="n">parents</span><span class="p">)</span>
        <span class="c1"># Initialize the return values</span>
        <span class="n">val_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
        <span class="n">p_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
        <span class="c1"># Initialize the optional return of the confidance matrix</span>
        <span class="n">conf_matrix</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">confidence</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">conf_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>

        <span class="c1"># Get the conditions as implied by the input arguments</span>
        <span class="k">for</span> <span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">,</span> <span class="n">Z</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_iter_indep_conds</span><span class="p">(</span><span class="n">_int_parents</span><span class="p">,</span>
                                                   <span class="n">_int_link_assumptions</span><span class="p">,</span>
                                                   <span class="n">max_conds_py</span><span class="p">,</span>
                                                   <span class="n">max_conds_px</span><span class="p">):</span>
            <span class="c1"># Set X and Y (for clarity of code)</span>
            <span class="n">X</span> <span class="o">=</span> <span class="p">[(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">)]</span>
            <span class="n">Y</span> <span class="o">=</span> <span class="p">[(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span>

            <span class="k">if</span> <span class="n">val_only</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span>
                <span class="c1"># Run the independence tests and record the results</span>
                <span class="k">if</span> <span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">))</span> <span class="ow">in</span> <span class="n">_int_link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> 
                     <span class="ow">and</span> <span class="n">_int_link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">][(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">))]</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;--&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;o-o&#39;</span><span class="p">]):</span>
                    <span class="n">val</span> <span class="o">=</span> <span class="mf">1.</span> 
                    <span class="n">pval</span> <span class="o">=</span> <span class="mf">0.</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">run_test</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span>
                                                        <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                                                        <span class="n">alpha_or_thres</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">,</span>
                                                        <span class="p">)</span>
                <span class="n">val_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span> <span class="o">=</span> <span class="n">val</span>
                <span class="n">p_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span> <span class="o">=</span> <span class="n">pval</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">val</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">get_measure</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>
                <span class="n">val_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span> <span class="o">=</span> <span class="n">val</span>

            <span class="c1"># Get the confidence value, returns None if cond_ind_test.confidence</span>
            <span class="c1"># is False</span>
            <span class="n">conf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">get_confidence</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">,</span> <span class="n">Z</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>
            <span class="c1"># Record the value if the conditional independence requires it</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">confidence</span><span class="p">:</span>
                <span class="n">conf_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span> <span class="o">=</span> <span class="n">conf</span>

        <span class="k">if</span> <span class="n">val_only</span><span class="p">:</span>
            <span class="n">results</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">:</span><span class="n">val_matrix</span><span class="p">,</span>
                       <span class="s1">&#39;conf_matrix&#39;</span><span class="p">:</span><span class="n">conf_matrix</span><span class="p">}</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="n">results</span>
            <span class="k">return</span> <span class="n">results</span>

        <span class="c1"># Correct the p_matrix if there is a fdr_method</span>
        <span class="k">if</span> <span class="n">fdr_method</span> <span class="o">!=</span> <span class="s1">&#39;none&#39;</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">significance</span> <span class="o">==</span> <span class="s1">&#39;fixed_thres&#39;</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;FDR-correction not compatible with significance == &#39;fixed_thres&#39;&quot;</span><span class="p">)</span>
            <span class="n">p_matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_corrected_pvalues</span><span class="p">(</span><span class="n">p_matrix</span><span class="o">=</span><span class="n">p_matrix</span><span class="p">,</span> <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span> 
                                                  <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> 
                                                  <span class="n">link_assumptions</span><span class="o">=</span><span class="n">_int_link_assumptions</span><span class="p">,</span>
                                                  <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span>

        <span class="c1"># Threshold p_matrix to get graph (or val_matrix for significance == &#39;fixed_thres&#39;)</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">significance</span> <span class="o">==</span> <span class="s1">&#39;fixed_thres&#39;</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">two_sided</span><span class="p">:</span>
                <span class="n">final_graph</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val_matrix</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">alpha_level</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">final_graph</span> <span class="o">=</span> <span class="n">val_matrix</span> <span class="o">&gt;=</span> <span class="n">alpha_level</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">final_graph</span> <span class="o">=</span> <span class="n">p_matrix</span> <span class="o">&lt;=</span> <span class="n">alpha_level</span>

        <span class="c1"># Convert to string graph representation</span>
        <span class="n">graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">convert_to_string_graph</span><span class="p">(</span><span class="n">final_graph</span><span class="p">)</span>

        <span class="c1"># Symmetrize p_matrix and val_matrix</span>
        <span class="n">symmetrized_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">symmetrize_p_and_val_matrix</span><span class="p">(</span>
                            <span class="n">p_matrix</span><span class="o">=</span><span class="n">p_matrix</span><span class="p">,</span> 
                            <span class="n">val_matrix</span><span class="o">=</span><span class="n">val_matrix</span><span class="p">,</span> 
                            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">_int_link_assumptions</span><span class="p">,</span>
                            <span class="n">conf_matrix</span><span class="o">=</span><span class="n">conf_matrix</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">print_significant_links</span><span class="p">(</span>
                    <span class="n">graph</span> <span class="o">=</span> <span class="n">graph</span><span class="p">,</span>
                    <span class="n">p_matrix</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span> 
                    <span class="n">val_matrix</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span>
                    <span class="n">conf_matrix</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;conf_matrix&#39;</span><span class="p">],</span>
                    <span class="n">alpha_level</span> <span class="o">=</span> <span class="n">alpha_level</span><span class="p">)</span>

        <span class="c1"># Return the values as a dictionary and store in class</span>
        <span class="n">results</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s1">&#39;graph&#39;</span><span class="p">:</span> <span class="n">graph</span><span class="p">,</span>
            <span class="s1">&#39;p_matrix&#39;</span><span class="p">:</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span>
            <span class="s1">&#39;val_matrix&#39;</span><span class="p">:</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span>
            <span class="s1">&#39;conf_matrix&#39;</span><span class="p">:</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;conf_matrix&#39;</span><span class="p">],</span>
                   <span class="p">}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="n">results</span>
        <span class="k">return</span> <span class="n">results</span>

<div class="viewcode-block" id="PCMCI.run_mci"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_mci">[docs]</a>    <span class="k">def</span> <span class="nf">run_mci</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                <span class="n">parents</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                <span class="n">max_conds_px</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                <span class="n">val_only</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;MCI conditional independence tests.</span>

<span class="sd">        Implements the MCI test (Algorithm 2 in [1]_). </span>

<span class="sd">        Returns the matrices of test statistic values, (optionally corrected) </span>
<span class="sd">        p-values, and (optionally) confidence intervals. Also (new in 4.3)</span>
<span class="sd">        returns graph based on alpha_level (and optional FDR-correction).</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, default: 0</span>
<span class="sd">            Minimum time lag to test. Note that zero-lags are undirected.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        parents : dict or None</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...}</span>
<span class="sd">            specifying the conditions for each variable. If None is</span>
<span class="sd">            passed, no conditions are used.</span>
<span class="sd">        max_conds_py : int or None</span>
<span class="sd">            Maximum number of conditions of Y to use. If None is passed, this</span>
<span class="sd">            number is unrestricted.</span>
<span class="sd">        max_conds_px : int or None</span>
<span class="sd">            Maximum number of conditions of Z to use. If None is passed, this</span>
<span class="sd">            number is unrestricted.</span>
<span class="sd">        val_only : bool, default: False</span>
<span class="sd">            Option to only compute dependencies and not p-values.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;none&#39;)</span>
<span class="sd">            Correction method, currently implemented is Benjamini-Hochberg</span>
<span class="sd">            False Discovery Rate method (&#39;fdr_bh&#39;). </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        conf_matrix : array of shape [N, N, tau_max+1,2]</span>
<span class="sd">            Estimated matrix of confidence intervals of test statistic values.</span>
<span class="sd">            Only computed if set in cond_ind_test, where also the percentiles</span>
<span class="sd">            are set.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>


        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Step 2: MCI algorithm</span><span class="se">\n</span><span class="s2">##&quot;</span>
                  <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">Parameters:&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">independence test = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">measure</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_min = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_min</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_max = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_max</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_py = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_py</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_px = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_px</span><span class="p">)</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_mci_or_variants</span><span class="p">(</span>
            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">parents</span><span class="o">=</span><span class="n">parents</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
            <span class="n">val_only</span><span class="o">=</span><span class="n">val_only</span><span class="p">,</span>
            <span class="n">alpha_level</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">,</span>
            <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span></div>

<div class="viewcode-block" id="PCMCI.get_lagged_dependencies"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.get_lagged_dependencies">[docs]</a>    <span class="k">def</span> <span class="nf">get_lagged_dependencies</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                                <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                                <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                                <span class="n">val_only</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                                <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                                <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Unconditional lagged independence tests.</span>

<span class="sd">        Implements the unconditional lagged independence test (see [ 1]_).</span>
<span class="sd">        </span>
<span class="sd">        Returns the matrices of test statistic values, (optionally corrected) </span>
<span class="sd">        p-values, and (optionally) confidence intervals. Also (new in 4.3)</span>
<span class="sd">        returns graph based on alpha_level (and optional FDR-correction).</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, default: 0</span>
<span class="sd">            Minimum time lag to test. Note that zero-lags are undirected.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        val_only : bool, default: False</span>
<span class="sd">            Option to only compute dependencies and not p-values.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;none&#39;)</span>
<span class="sd">            Correction method, currently implemented is Benjamini-Hochberg</span>
<span class="sd">            False Discovery Rate method (&#39;fdr_bh&#39;).  </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        conf_matrix : array of shape [N, N, tau_max+1,2]</span>
<span class="sd">            Estimated matrix of confidence intervals of test statistic values.</span>
<span class="sd">            Only computed if set in cond_ind_test, where also the percentiles</span>
<span class="sd">            are set.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Estimating lagged dependencies </span><span class="se">\n</span><span class="s2">##&quot;</span>
                  <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">Parameters:&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">independence test = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">measure</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_min = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_min</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_max = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_mci_or_variants</span><span class="p">(</span>
            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">parents</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
            <span class="n">val_only</span><span class="o">=</span><span class="n">val_only</span><span class="p">,</span>
            <span class="n">alpha_level</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">,</span>
            <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span></div>

<div class="viewcode-block" id="PCMCI.run_fullci"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_fullci">[docs]</a>    <span class="k">def</span> <span class="nf">run_fullci</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                   <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                   <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                   <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                   <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                   <span class="n">val_only</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                   <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                   <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;FullCI conditional independence tests.</span>

<span class="sd">        Implements the FullCI test (see [1]_). </span>

<span class="sd">        Returns the matrices of test statistic values, (optionally corrected) </span>
<span class="sd">        p-values, and (optionally) confidence intervals. Also (new in 4.3)</span>
<span class="sd">        returns graph based on alpha_level (and optional FDR-correction).</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, default: 0</span>
<span class="sd">            Minimum time lag to test. Note that zero-lags are undirected.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        val_only : bool, default: False</span>
<span class="sd">            Option to only compute dependencies and not p-values.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;none&#39;)</span>
<span class="sd">            Correction method, currently implemented is Benjamini-Hochberg</span>
<span class="sd">            False Discovery Rate method (&#39;fdr_bh&#39;).  </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        conf_matrix : array of shape [N, N, tau_max+1,2]</span>
<span class="sd">            Estimated matrix of confidence intervals of test statistic values.</span>
<span class="sd">            Only computed if set in cond_ind_test, where also the percentiles</span>
<span class="sd">            are set.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>


        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Running Tigramite FullCI algorithm</span><span class="se">\n</span><span class="s2">##&quot;</span>
                  <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">Parameters:&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">independence test = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">measure</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_min = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_min</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_max = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="n">full_past</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">j</span><span class="p">,</span> <span class="p">[(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)</span>
                               <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)</span>
                               <span class="k">for</span> <span class="n">tau</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">),</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)])</span>
                          <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)])</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_mci_or_variants</span><span class="p">(</span>
            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">parents</span><span class="o">=</span><span class="n">full_past</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
            <span class="n">val_only</span><span class="o">=</span><span class="n">val_only</span><span class="p">,</span>
            <span class="n">alpha_level</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">,</span>
            <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span></div>

<div class="viewcode-block" id="PCMCI.run_bivci"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_bivci">[docs]</a>    <span class="k">def</span> <span class="nf">run_bivci</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                  <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                  <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                  <span class="n">val_only</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                  <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                  <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;BivCI conditional independence tests.</span>

<span class="sd">        Implements the BivCI test (see [1]_). </span>

<span class="sd">        Returns the matrices of test statistic values, (optionally corrected) </span>
<span class="sd">        p-values, and (optionally) confidence intervals. Also (new in 4.3)</span>
<span class="sd">        returns graph based on alpha_level (and optional FDR-correction).</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, default: 0</span>
<span class="sd">            Minimum time lag to test. Note that zero-lags are undirected.</span>
<span class="sd">        tau_max : int, default: 1</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        val_only : bool, default: False</span>
<span class="sd">            Option to only compute dependencies and not p-values.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;fdr_bh&#39;)</span>
<span class="sd">            Correction method, currently implemented is Benjamini-Hochberg</span>
<span class="sd">            False Discovery Rate method. </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        conf_matrix : array of shape [N, N, tau_max+1,2]</span>
<span class="sd">            Estimated matrix of confidence intervals of test statistic values.</span>
<span class="sd">            Only computed if set in cond_ind_test, where also the percentiles</span>
<span class="sd">            are set.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Running Tigramite BivCI algorithm</span><span class="se">\n</span><span class="s2">##&quot;</span>
                  <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">Parameters:&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">independence test = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">measure</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_min = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_min</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_max = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="n">auto_past</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">j</span><span class="p">,</span> <span class="p">[(</span><span class="n">j</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">)</span>
                               <span class="k">for</span> <span class="n">tau</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">),</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)])</span>
                          <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)])</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_mci_or_variants</span><span class="p">(</span>
            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">parents</span><span class="o">=</span><span class="n">auto_past</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
            <span class="n">val_only</span><span class="o">=</span><span class="n">val_only</span><span class="p">,</span>
            <span class="n">alpha_level</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">,</span>
            <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span></div>

<div class="viewcode-block" id="PCMCI.get_graph_from_pmatrix"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.get_graph_from_pmatrix">[docs]</a>    <span class="k">def</span> <span class="nf">get_graph_from_pmatrix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">p_matrix</span><span class="p">,</span> <span class="n">alpha_level</span><span class="p">,</span> 
            <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Construct graph from thresholding the p_matrix at an alpha-level.</span>

<span class="sd">        Allows to take into account link_assumptions.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        tau_mix : int</span>
<span class="sd">            Minimum time delay to test.</span>
<span class="sd">        tau_max : int</span>
<span class="sd">            Maximum time delay to test.</span>
<span class="sd">        link_assumptions : dict or None</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        &quot;&quot;&quot;</span>  

        <span class="c1"># _int_sel_links = self._set_sel_links(selected_links, tau_min, tau_max)</span>
        <span class="n">_int_link_assumptions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_link_assumptions</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">link_assumptions</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># Create a mask for these values</span>
            <span class="n">mask</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="s1">&#39;bool&#39;</span><span class="p">)</span>
            <span class="c1"># for node1, links_ in _int_sel_links.items():</span>
            <span class="c1">#     for node2, lag in links_:</span>
            <span class="c1">#         mask[node2, node1, abs(lag)] = True</span>
            <span class="k">for</span> <span class="n">j</span><span class="p">,</span> <span class="n">links_</span> <span class="ow">in</span> <span class="n">_int_link_assumptions</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">lag</span> <span class="ow">in</span> <span class="n">links_</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">_int_link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">][(</span><span class="n">i</span><span class="p">,</span> <span class="n">lag</span><span class="p">)]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;&lt;--&quot;</span><span class="p">,</span> <span class="s2">&quot;&lt;?-&quot;</span><span class="p">]:</span>
                        <span class="n">mask</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">lag</span><span class="p">)]</span> <span class="o">=</span> <span class="kc">True</span>

        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Create a mask for these values</span>
            <span class="n">mask</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="s1">&#39;bool&#39;</span><span class="p">)</span>

        <span class="c1"># Set all p-values of absent links to 1.</span>
        <span class="n">p_matrix</span><span class="p">[</span><span class="n">mask</span><span class="o">==</span><span class="kc">False</span><span class="p">]</span> <span class="o">==</span> <span class="mf">1.</span>

        <span class="c1"># Threshold p_matrix to get graph</span>
        <span class="n">graph_bool</span> <span class="o">=</span> <span class="n">p_matrix</span> <span class="o">&lt;=</span> <span class="n">alpha_level</span>

        <span class="c1"># Convert to string graph representation</span>
        <span class="n">graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">convert_to_string_graph</span><span class="p">(</span><span class="n">graph_bool</span><span class="p">)</span>

        <span class="c1"># Return the graph</span>
        <span class="k">return</span> <span class="n">graph</span></div>

<div class="viewcode-block" id="PCMCI.return_parents_dict"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.return_parents_dict">[docs]</a>    <span class="k">def</span> <span class="nf">return_parents_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span>
                             <span class="n">val_matrix</span><span class="p">,</span>
                             <span class="n">include_lagzero_parents</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns dictionary of parents sorted by val_matrix.</span>

<span class="sd">        If parents are unclear (edgemarks with &#39;o&#39; or &#39;x&#39;, or middle mark &#39;?&#39;), </span>
<span class="sd">        then no parent is returned. </span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array-like</span>
<span class="sd">            Matrix of test statistic values. Must be of shape (N, N, tau_max +</span>
<span class="sd">            1).</span>
<span class="sd">        include_lagzero_parents : bool (default: False)</span>
<span class="sd">            Whether the dictionary should also return parents at lag</span>
<span class="sd">            zero. </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        parents_dict : dict</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...}</span>
<span class="sd">            containing estimated parents.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="c1"># Initialize the return value</span>
        <span class="n">parents_dict</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="c1"># Get the good links</span>
            <span class="k">if</span> <span class="n">include_lagzero_parents</span><span class="p">:</span>
                <span class="n">good_links</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">graph</span><span class="p">[:,</span> <span class="n">j</span><span class="p">,</span> <span class="p">:]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span><span class="p">)</span>
                <span class="c1"># Build a dictionary from these links to their values</span>
                <span class="n">links</span> <span class="o">=</span> <span class="p">{(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">):</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)])</span>
                         <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="ow">in</span> <span class="n">good_links</span><span class="p">}</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">good_links</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">graph</span><span class="p">[:,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">1</span><span class="p">:]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span><span class="p">)</span>
                <span class="c1"># Build a dictionary from these links to their values</span>
                <span class="n">links</span> <span class="o">=</span> <span class="p">{(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span> <span class="o">-</span> <span class="mi">1</span><span class="p">):</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">])</span>
                         <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="ow">in</span> <span class="n">good_links</span><span class="p">}</span>
            <span class="c1"># Sort by value</span>
            <span class="n">parents_dict</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">links</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">links</span><span class="o">.</span><span class="n">get</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
        
        <span class="k">return</span> <span class="n">parents_dict</span></div>
               

<div class="viewcode-block" id="PCMCI.return_significant_links"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.return_significant_links">[docs]</a>    <span class="k">def</span> <span class="nf">return_significant_links</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pq_matrix</span><span class="p">,</span>
                                 <span class="n">val_matrix</span><span class="p">,</span>
                                 <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                                 <span class="n">include_lagzero_links</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns list of significant links as well as a boolean matrix.</span>

<span class="sd">        DEPRECATED. Will be removed in future.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;return_significant_links() is DEPRECATED: now run_pcmci(), &quot;</span>
              <span class="s2">&quot; run_mci()&quot;</span>
              <span class="s2">&quot; and all variants directly return the graph based on thresholding &quot;</span>
              <span class="s2">&quot;the p_matrix at alpha_level. The graph can also be updated &quot;</span>
              <span class="s2">&quot;based on a (potentially further adjusted) p_matrix using &quot;</span>
              <span class="s2">&quot;get_graph_from_pmatrix(). &quot;</span>
              <span class="s2">&quot;A dictionary of parents can be obtained &quot;</span>
              <span class="s2">&quot;with return_parents_dict().&quot;</span><span class="p">)</span>
        <span class="k">return</span> <span class="kc">None</span></div>

<div class="viewcode-block" id="PCMCI.print_significant_links"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.print_significant_links">[docs]</a>    <span class="k">def</span> <span class="nf">print_significant_links</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                                <span class="n">p_matrix</span><span class="p">,</span>
                                <span class="n">val_matrix</span><span class="p">,</span>
                                <span class="n">conf_matrix</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                <span class="n">graph</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                <span class="n">ambiguous_triples</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Prints significant links.</span>

<span class="sd">        Used for output of PCMCI and PCMCIplus. For the latter also information</span>
<span class="sd">        on ambiguous links and conflicts is returned.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level.</span>
<span class="sd">        p_matrix : array-like</span>
<span class="sd">            Must be of shape (N, N, tau_max + 1).</span>
<span class="sd">        val_matrix : array-like</span>
<span class="sd">            Must be of shape (N, N, tau_max + 1).</span>
<span class="sd">        conf_matrix : array-like, optional (default: None)</span>
<span class="sd">            Matrix of confidence intervals of shape (N, N, tau_max+1, 2).</span>
<span class="sd">        graph : array-like</span>
<span class="sd">            Must be of shape (N, N, tau_max + 1).</span>
<span class="sd">        ambiguous_triples : list</span>
<span class="sd">            List of ambiguous triples.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">graph</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">sig_links</span> <span class="o">=</span> <span class="p">(</span><span class="n">graph</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">graph</span> <span class="o">!=</span> <span class="s2">&quot;&lt;--&quot;</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">sig_links</span> <span class="o">=</span> <span class="p">(</span><span class="n">p_matrix</span> <span class="o">&lt;=</span> <span class="n">alpha_level</span><span class="p">)</span>

        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">## Significant links at alpha = </span><span class="si">%s</span><span class="s2">:&quot;</span> <span class="o">%</span> <span class="n">alpha_level</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="n">links</span> <span class="o">=</span> <span class="p">{(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="o">-</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val_matrix</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])])</span>
                     <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">sig_links</span><span class="p">[:,</span> <span class="n">j</span><span class="p">,</span> <span class="p">:]))}</span>
            <span class="c1"># Sort by value</span>
            <span class="n">sorted_links</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">links</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">links</span><span class="o">.</span><span class="n">get</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
            <span class="n">n_links</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">links</span><span class="p">)</span>
            <span class="n">string</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Variable </span><span class="si">%s</span><span class="s2"> has </span><span class="si">%d</span><span class="s2"> &quot;</span>
                      <span class="s2">&quot;link(s):&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">n_links</span><span class="p">))</span>
            <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">sorted_links</span><span class="p">:</span>
                <span class="n">string</span> <span class="o">+=</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">        (</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">): pval = </span><span class="si">%.5f</span><span class="s2">&quot;</span> <span class="o">%</span>
                           <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
                            <span class="n">p_matrix</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])]))</span>
                <span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot; | val = </span><span class="si">% .3f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                    <span class="n">val_matrix</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])])</span>
                <span class="k">if</span> <span class="n">conf_matrix</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot; | conf = (</span><span class="si">%.3f</span><span class="s2">, </span><span class="si">%.3f</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
                        <span class="n">conf_matrix</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])][</span><span class="mi">0</span><span class="p">],</span>
                        <span class="n">conf_matrix</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])][</span><span class="mi">1</span><span class="p">])</span>
                <span class="k">if</span> <span class="n">graph</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;o-o&quot;</span><span class="p">:</span>
                        <span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot; | unoriented link&quot;</span>
                    <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">])]</span> <span class="o">==</span> <span class="s2">&quot;x-x&quot;</span><span class="p">:</span>
                        <span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot; | unclear orientation due to conflict&quot;</span>
            <span class="nb">print</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>

        <span class="c1"># link_marker = {True:&quot;o-o&quot;, False:&quot;--&gt;&quot;}</span>

        <span class="k">if</span> <span class="n">ambiguous_triples</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">ambiguous_triples</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">## Ambiguous triples (not used for orientation):</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">triple</span> <span class="ow">in</span> <span class="n">ambiguous_triples</span><span class="p">:</span>
                <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">triple</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;    [(</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">), </span><span class="si">%s</span><span class="s2">, </span><span class="si">%s</span><span class="s2">]&quot;</span> <span class="o">%</span> <span class="p">(</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">tau</span><span class="p">,</span> 
                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span></div>

<div class="viewcode-block" id="PCMCI.print_results"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.print_results">[docs]</a>    <span class="k">def</span> <span class="nf">print_results</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                      <span class="n">return_dict</span><span class="p">,</span>
                      <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Prints significant parents from output of MCI or PCMCI algorithms.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        return_dict : dict</span>
<span class="sd">            Dictionary of return values, containing keys</span>
<span class="sd">                * &#39;p_matrix&#39;</span>
<span class="sd">                * &#39;val_matrix&#39;</span>
<span class="sd">                * &#39;conf_matrix&#39;</span>

<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Check if conf_matrix is defined</span>
        <span class="n">conf_matrix</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">conf_key</span> <span class="o">=</span> <span class="s1">&#39;conf_matrix&#39;</span>
        <span class="k">if</span> <span class="n">conf_key</span> <span class="ow">in</span> <span class="n">return_dict</span><span class="p">:</span>
            <span class="n">conf_matrix</span> <span class="o">=</span> <span class="n">return_dict</span><span class="p">[</span><span class="n">conf_key</span><span class="p">]</span>
        <span class="c1"># Wrap the already defined function</span>
        <span class="k">if</span> <span class="s1">&#39;graph&#39;</span> <span class="ow">in</span> <span class="n">return_dict</span><span class="p">:</span>
            <span class="n">graph</span> <span class="o">=</span> <span class="n">return_dict</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">graph</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">if</span> <span class="s1">&#39;ambiguous_triples&#39;</span> <span class="ow">in</span> <span class="n">return_dict</span><span class="p">:</span>
            <span class="n">ambiguous_triples</span> <span class="o">=</span> <span class="n">return_dict</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">ambiguous_triples</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">print_significant_links</span><span class="p">(</span><span class="n">return_dict</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span>
                                     <span class="n">return_dict</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span>
                                     <span class="n">conf_matrix</span><span class="o">=</span><span class="n">conf_matrix</span><span class="p">,</span>
                                     <span class="n">graph</span><span class="o">=</span><span class="n">graph</span><span class="p">,</span>
                                     <span class="n">ambiguous_triples</span><span class="o">=</span><span class="n">ambiguous_triples</span><span class="p">,</span>
                                     <span class="n">alpha_level</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">)</span></div>

<div class="viewcode-block" id="PCMCI.run_pcmci"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_pcmci">[docs]</a>    <span class="k">def</span> <span class="nf">run_pcmci</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                  <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                  <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                  <span class="n">save_iterations</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                  <span class="n">pc_alpha</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                  <span class="n">max_conds_dim</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">max_combinations</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                  <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">max_conds_px</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                  <span class="n">alpha_level</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                  <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Runs PCMCI time-lagged causal discovery for time series.</span>

<span class="sd">        Wrapper around PC-algorithm function and MCI function.</span>

<span class="sd">        Notes</span>
<span class="sd">        -----</span>

<span class="sd">        The PCMCI causal discovery method is comprehensively described in [</span>
<span class="sd">        1]_, where also analytical and numerical results are presented. Here</span>
<span class="sd">        we briefly summarize the method.</span>

<span class="sd">        PCMCI estimates time-lagged causal links by a two-step procedure:</span>

<span class="sd">        1.  Condition-selection: For each variable :math:`j`, estimate a</span>
<span class="sd">            *superset* of parents :math:`\\tilde{\mathcal{P}}(X^j_t)` with the</span>
<span class="sd">            iterative PC1 algorithm, implemented as ``run_pc_stable``. The</span>
<span class="sd">            condition-selection step reduces the dimensionality and avoids</span>
<span class="sd">            conditioning on irrelevant variables.</span>

<span class="sd">        2.  *Momentary conditional independence* (MCI)</span>

<span class="sd">        .. math:: X^i_{t-\\tau} \perp X^j_{t} | \\tilde{\\mathcal{P}}(</span>
<span class="sd">                  X^j_t), \\tilde{\mathcal{P}}(X^i_{t-\\tau})</span>

<span class="sd">        here implemented as ``run_mci``. This step estimates the p-values and</span>
<span class="sd">        test statistic values for all links accounting for common drivers,</span>
<span class="sd">        indirect links, and autocorrelation.</span>

<span class="sd">        NOTE: MCI test statistic values define a particular measure of causal</span>
<span class="sd">        strength depending on the test statistic used. For example, ParCorr()</span>
<span class="sd">        results in normalized values between -1 and 1. However, if you are </span>
<span class="sd">        interested in quantifying causal effects, i.e., the effect of</span>
<span class="sd">        hypothetical interventions, you may better look at the causal effect </span>
<span class="sd">        estimation functionality of Tigramite.</span>

<span class="sd">        PCMCI can be flexibly combined with any kind of conditional</span>
<span class="sd">        independence test statistic adapted to the kind of data (continuous</span>
<span class="sd">        or discrete) and its assumed dependency types. These are available in</span>
<span class="sd">        ``tigramite.independence_tests``.</span>

<span class="sd">        The main free parameters of PCMCI (in addition to free parameters of</span>
<span class="sd">        the conditional independence test statistic) are the maximum time</span>
<span class="sd">        delay :math:`\\tau_{\\max}` (``tau_max``) and the significance</span>
<span class="sd">        threshold in the condition-selection step :math:`\\alpha` (</span>
<span class="sd">        ``pc_alpha``). The maximum time delay depends on the application and</span>
<span class="sd">        should be chosen according to the maximum causal time lag expected in</span>
<span class="sd">        the complex system. We recommend a rather large choice that includes</span>
<span class="sd">        peaks in the ``get_lagged_dependencies`` function. :math:`\\alpha`</span>
<span class="sd">        should not be seen as a significance test level in the</span>
<span class="sd">        condition-selection step since the iterative hypothesis tests do not</span>
<span class="sd">        allow for a precise assessment. :math:`\\alpha` rather takes the role</span>
<span class="sd">        of a regularization parameter in model-selection techniques. If a</span>
<span class="sd">        list of values is given or ``pc_alpha=None``, :math:`\\alpha` is</span>
<span class="sd">        optimized using model selection criteria implemented in the respective</span>
<span class="sd">        ``tigramite.independence_tests``.</span>

<span class="sd">        Further optional parameters are discussed in [1]_.</span>

<span class="sd">        Examples</span>
<span class="sd">        --------</span>
<span class="sd">        &gt;&gt;&gt; import numpy</span>
<span class="sd">        &gt;&gt;&gt; from tigramite.pcmci import PCMCI</span>
<span class="sd">        &gt;&gt;&gt; from tigramite.independence_tests import ParCorr</span>
<span class="sd">        &gt;&gt;&gt; import tigramite.data_processing as pp</span>
<span class="sd">        &gt;&gt;&gt; from tigramite.toymodels import structural_causal_processes as toys</span>
<span class="sd">        &gt;&gt;&gt; numpy.random.seed(7)</span>
<span class="sd">        &gt;&gt;&gt; # Example process to play around with</span>
<span class="sd">        &gt;&gt;&gt; # Each key refers to a variable and the incoming links are supplied</span>
<span class="sd">        &gt;&gt;&gt; # as a list of format [((driver, -lag), coeff), ...]</span>
<span class="sd">        &gt;&gt;&gt; links_coeffs = {0: [((0, -1), 0.8)],</span>
<span class="sd">                            1: [((1, -1), 0.8), ((0, -1), 0.5)],</span>
<span class="sd">                            2: [((2, -1), 0.8), ((1, -2), -0.6)]}</span>
<span class="sd">        &gt;&gt;&gt; data, _ = toys.var_process(links_coeffs, T=1000)</span>
<span class="sd">        &gt;&gt;&gt; # Data must be array of shape (time, variables)</span>
<span class="sd">        &gt;&gt;&gt; print (data.shape)</span>
<span class="sd">        (1000, 3)</span>
<span class="sd">        &gt;&gt;&gt; dataframe = pp.DataFrame(data)</span>
<span class="sd">        &gt;&gt;&gt; cond_ind_test = ParCorr()</span>
<span class="sd">        &gt;&gt;&gt; pcmci = PCMCI(dataframe=dataframe, cond_ind_test=cond_ind_test)</span>
<span class="sd">        &gt;&gt;&gt; results = pcmci.run_pcmci(tau_max=2, pc_alpha=None)</span>
<span class="sd">        &gt;&gt;&gt; pcmci.print_significant_links(p_matrix=results[&#39;p_matrix&#39;],</span>
<span class="sd">                                         val_matrix=results[&#39;val_matrix&#39;],</span>
<span class="sd">                                         alpha_level=0.05)</span>
<span class="sd">        ## Significant parents at alpha = 0.05:</span>

<span class="sd">            Variable 0 has 1 link(s):</span>
<span class="sd">                (0 -1): pval = 0.00000 | val =  0.588</span>

<span class="sd">            Variable 1 has 2 link(s):</span>
<span class="sd">                (1 -1): pval = 0.00000 | val =  0.606</span>
<span class="sd">                (0 -1): pval = 0.00000 | val =  0.447</span>

<span class="sd">            Variable 2 has 2 link(s):</span>
<span class="sd">                (2 -1): pval = 0.00000 | val =  0.618</span>
<span class="sd">                (1 -2): pval = 0.00000 | val = -0.499</span>


<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, optional (default: 0)</span>
<span class="sd">            Minimum time lag to test. Note that zero-lags are undirected.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        save_iterations : bool, optional (default: False)</span>
<span class="sd">            Whether to save iteration step results such as conditions used.</span>
<span class="sd">        pc_alpha : float, optional (default: 0.05)</span>
<span class="sd">            Significance level in algorithm.</span>
<span class="sd">        max_conds_dim : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int, optional (default: 1)</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test in PC1 step.</span>
<span class="sd">        max_conds_py : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions of Y to use. If None is passed, this</span>
<span class="sd">            number is unrestricted.</span>
<span class="sd">        max_conds_px : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions of Z to use. If None is passed, this</span>
<span class="sd">            number is unrestricted.</span>
<span class="sd">        alpha_level : float, optional (default: 0.05)</span>
<span class="sd">            Significance level at which the p_matrix is thresholded to </span>
<span class="sd">            get graph.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;fdr_bh&#39;)</span>
<span class="sd">            Correction method, currently implemented is Benjamini-Hochberg</span>
<span class="sd">            False Discovery Rate method. </span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values, optionally adjusted if fdr_method is</span>
<span class="sd">            not &#39;none&#39;.</span>
<span class="sd">        conf_matrix : array of shape [N, N, tau_max+1,2]</span>
<span class="sd">            Estimated matrix of confidence intervals of test statistic values.</span>
<span class="sd">            Only computed if set in cond_ind_test, where also the percentiles</span>
<span class="sd">            are set.</span>

<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>


        <span class="c1"># Get the parents from run_pc_stable</span>
        <span class="n">all_parents</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_pc_stable</span><span class="p">(</span><span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
                                         <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
                                         <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                                         <span class="n">save_iterations</span><span class="o">=</span><span class="n">save_iterations</span><span class="p">,</span>
                                         <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
                                         <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
                                         <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">)</span>

        <span class="c1"># Get the results from run_mci, using the parents as the input</span>
        <span class="n">results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_mci</span><span class="p">(</span><span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
                               <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
                               <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                               <span class="n">parents</span><span class="o">=</span><span class="n">all_parents</span><span class="p">,</span>
                               <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
                               <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
                               <span class="n">alpha_level</span><span class="o">=</span><span class="n">alpha_level</span><span class="p">,</span>
                               <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span>
    
        <span class="c1"># Store the parents in the pcmci member</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">all_parents</span> <span class="o">=</span> <span class="n">all_parents</span>

        <span class="c1"># Print the information</span>
        <span class="c1"># if self.verbosity &gt; 0:</span>
        <span class="c1">#     self.print_results(results)</span>
        <span class="c1"># Return the dictionary</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="n">results</span>
        <span class="k">return</span> <span class="n">results</span></div>

<div class="viewcode-block" id="PCMCI.run_pcmciplus"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_pcmciplus">[docs]</a>    <span class="k">def</span> <span class="nf">run_pcmciplus</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                      <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                      <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                      <span class="n">pc_alpha</span><span class="o">=</span><span class="mf">0.01</span><span class="p">,</span>
                      <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="s1">&#39;majority&#39;</span><span class="p">,</span>
                      <span class="n">conflict_resolution</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
                      <span class="n">reset_lagged_links</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                      <span class="n">max_conds_dim</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">max_combinations</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
                      <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">max_conds_px</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                      <span class="n">fdr_method</span><span class="o">=</span><span class="s1">&#39;none&#39;</span><span class="p">,</span>
                      <span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Runs PCMCIplus time-lagged and contemporaneous causal discovery for</span>
<span class="sd">        time series.</span>

<span class="sd">        Method described in [5]: </span>
<span class="sd">        http://www.auai.org/~w-auai/uai2020/proceedings/579_main_paper.pdf</span>

<span class="sd">        [5] J. Runge, Discovering contemporaneous and lagged causal relations</span>
<span class="sd">        in autocorrelated nonlinear time series datasets</span>
<span class="sd">        http://www.auai.org/~w-auai/uai2020/proceedings/579_main_paper.pdf</span>

<span class="sd">        Notes</span>
<span class="sd">        -----</span>

<span class="sd">        The PCMCIplus causal discovery method is described in [5], where</span>
<span class="sd">        also analytical and numerical results are presented. In contrast to</span>
<span class="sd">        PCMCI, PCMCIplus can identify the full, lagged and contemporaneous,</span>
<span class="sd">        causal graph (up to the Markov equivalence class for contemporaneous</span>
<span class="sd">        links) under the standard assumptions of Causal Sufficiency,</span>
<span class="sd">        Faithfulness and the Markov condition.</span>

<span class="sd">        PCMCIplus estimates time-lagged and contemporaneous causal links by a</span>
<span class="sd">        four-step procedure:</span>

<span class="sd">        1.  Condition-selection (same as for PCMCI): For each variable</span>
<span class="sd">        :math:`j`, estimate a *superset* of lagged parents :math:`\widehat{</span>
<span class="sd">        \mathcal{B}}_t^-( X^j_t)` with the iterative PC1 algorithm,</span>
<span class="sd">        implemented as ``run_pc_stable``. The condition-selection step</span>
<span class="sd">        reduces the dimensionality and avoids conditioning on irrelevant</span>
<span class="sd">        variables.</span>

<span class="sd">        2.   PC skeleton phase with contemporaneous conditions and *Momentary</span>
<span class="sd">        conditional independence* (MCI) tests: Iterate through subsets</span>
<span class="sd">        :math:`\\mathcal{S}` of contemporaneous adjacencies and conduct MCI</span>
<span class="sd">        conditional independence tests:</span>

<span class="sd">        .. math:: X^i_{t-\\tau} ~\\perp~ X^j_{t} ~|~ \\mathcal{S},</span>
<span class="sd">                  \\widehat{\\mathcal{B}}_t^-(X^j_t),</span>
<span class="sd">                  \\widehat{\\mathcal{B}}_{t-\\tau}^-(X^i_{t-{\\tau}})</span>

<span class="sd">        here implemented as ``run_pcalg``. This step estimates the p-values and</span>
<span class="sd">        test statistic values for all lagged and contemporaneous adjacencies</span>
<span class="sd">        accounting for common drivers, indirect links, and autocorrelation.</span>

<span class="sd">        3.   PC collider orientation phase: Orient contemporaneous collider</span>
<span class="sd">        motifs based on unshielded triples. Optionally apply conservative or</span>
<span class="sd">        majority rule (also based on MCI tests).</span>

<span class="sd">        4.   PC rule orientation phase: Orient remaining contemporaneous</span>
<span class="sd">        links based on PC rules.</span>

<span class="sd">        In contrast to PCMCI, the relevant output of PCMCIplus is the</span>
<span class="sd">        array ``graph``. Its string entries are interpreted as follows:</span>

<span class="sd">        * ``graph[i,j,tau]=--&gt;`` for :math:`\\tau&gt;0` denotes a directed, lagged</span>
<span class="sd">          causal link from :math:`i` to :math:`j` at lag :math:`\\tau`</span>

<span class="sd">        * ``graph[i,j,0]=--&gt;`` (and ``graph[j,i,0]=&lt;--``) denotes a directed,</span>
<span class="sd">          contemporaneous causal link from :math:`i` to :math:`j`</span>

<span class="sd">        * ``graph[i,j,0]=o-o`` (and ``graph[j,i,0]=o-o``) denotes an unoriented,</span>
<span class="sd">          contemporaneous adjacency between :math:`i` and :math:`j` indicating</span>
<span class="sd">          that the collider and orientation rules could not be applied (Markov</span>
<span class="sd">          equivalence)</span>

<span class="sd">        * ``graph[i,j,0]=x-x`` and (``graph[j,i,0]=x-x``) denotes a conflicting,</span>
<span class="sd">          contemporaneous adjacency between :math:`i` and :math:`j` indicating</span>
<span class="sd">          that the directionality is undecided due to conflicting orientation</span>
<span class="sd">          rules</span>

<span class="sd">        Importantly, ``p_matrix`` and ``val_matrix`` for PCMCIplus quantify</span>
<span class="sd">        the uncertainty and strength, respectively, only for the</span>
<span class="sd">        adjacencies, but not for the directionality of contemporaneous links.</span>
<span class="sd">        Note that lagged links are always oriented due to time order.</span>

<span class="sd">        PCMCIplus can be flexibly combined with any kind of conditional</span>
<span class="sd">        independence test statistic adapted to the kind of data (continuous</span>
<span class="sd">        or discrete) and its assumed dependency types. These are available in</span>
<span class="sd">        ``tigramite.independence_tests``.</span>

<span class="sd">        The main free parameters of PCMCIplus (in addition to free parameters of</span>
<span class="sd">        the conditional independence tests) are the maximum time delay</span>
<span class="sd">        :math:`\\tau_{\\max}` (``tau_max``) and the significance threshold</span>
<span class="sd">        :math:`\\alpha` ( ``pc_alpha``). </span>

<span class="sd">        If a list or None is passed for ``pc_alpha``, the significance level is</span>
<span class="sd">        optimized for every graph across the given ``pc_alpha`` values using the</span>
<span class="sd">        score computed in ``cond_ind_test.get_model_selection_criterion()``.</span>
<span class="sd">        Since PCMCIplus outputs not a DAG, but an equivalence class of DAGs,</span>
<span class="sd">        first one member of this class is computed and then the score is</span>
<span class="sd">        computed as the average over all models fits for each variable in ``[0,</span>
<span class="sd">        ..., N]`` for that member. The score is the same for all members of the</span>
<span class="sd">        class.</span>

<span class="sd">        The maximum time delay depends on the application and should be chosen</span>
<span class="sd">        according to the maximum causal time lag expected in the complex system.</span>
<span class="sd">        We recommend a rather large choice that includes peaks in the</span>
<span class="sd">        ``get_lagged_dependencies`` function. Another important parameter is</span>
<span class="sd">        ``contemp_collider_rule``. Only if set to ``majority`` or</span>
<span class="sd">        ``conservative&#39;&#39; and together with ``conflict_resolution=True``,</span>
<span class="sd">        PCMCIplus is fully *order independent* meaning that the order of the N</span>
<span class="sd">        variables in the dataframe does not matter. Last, the default option</span>
<span class="sd">        ``reset_lagged_links=False`` restricts the detection of lagged causal</span>
<span class="sd">        links in Step 2 to the significant adjacencies found in Step 1, given by</span>
<span class="sd">        :math:`\\widehat{ \\mathcal{B}}_t^-( X^j_t)`. For</span>
<span class="sd">        ``reset_lagged_links=True``, *all* lagged links are considered again,</span>
<span class="sd">        which improves detection power for lagged links, but also leads to</span>
<span class="sd">        larger runtimes.</span>

<span class="sd">        Further optional parameters are discussed in [5].</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        tau_min : int, optional (default: 0)</span>
<span class="sd">            Minimum time lag to test.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        pc_alpha : float or list of floats, default: 0.01</span>
<span class="sd">            Significance level in algorithm. If a list or None is passed, the</span>
<span class="sd">            pc_alpha level is optimized for every graph across the given</span>
<span class="sd">            pc_alpha values ([0.001, 0.005, 0.01, 0.025, 0.05] for None) using</span>
<span class="sd">            the score computed in cond_ind_test.get_model_selection_criterion().</span>
<span class="sd">        contemp_collider_rule : {&#39;majority&#39;, &#39;conservative&#39;, &#39;none&#39;}</span>
<span class="sd">            Rule for collider phase to use. See the paper for details. Only</span>
<span class="sd">            &#39;majority&#39; and &#39;conservative&#39; lead to an order-independent</span>
<span class="sd">            algorithm.</span>
<span class="sd">        conflict_resolution : bool, optional (default: True)</span>
<span class="sd">            Whether to mark conflicts in orientation rules. Only for True</span>
<span class="sd">            this leads to an order-independent algorithm.</span>
<span class="sd">        reset_lagged_links : bool, optional (default: False)</span>
<span class="sd">            Restricts the detection of lagged causal links in Step 2 to the</span>
<span class="sd">            significant adjacencies found in the PC1 algorithm in Step 1. For</span>
<span class="sd">            True, *all* lagged links are considered again, which improves</span>
<span class="sd">            detection power for lagged links, but also leads to larger</span>
<span class="sd">            runtimes.</span>
<span class="sd">        max_conds_dim : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int, optional (default: 1)</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test in PC1 step.</span>
<span class="sd">        max_conds_py : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of Y to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px_lagged : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X when X is lagged in MCI </span>
<span class="sd">            tests. If None is passed, this number is equal to max_conds_px.</span>
<span class="sd">        fdr_method : str, optional (default: &#39;none&#39;)</span>
<span class="sd">            Correction method, default is Benjamini-Hochberg False Discovery</span>
<span class="sd">            Rate method.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Resulting causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values regarding adjacencies.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values regarding adjacencies.</span>
<span class="sd">        sepsets : dictionary</span>
<span class="sd">            Separating sets. See paper for details.</span>
<span class="sd">        ambiguous_triples : list</span>
<span class="sd">            List of ambiguous triples, only relevant for &#39;majority&#39; and</span>
<span class="sd">            &#39;conservative&#39; rules, see paper for details.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>

        <span class="c1"># Check if pc_alpha is chosen to optimze over a list</span>
        <span class="k">if</span> <span class="n">pc_alpha</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pc_alpha</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">)):</span>
            <span class="c1"># Call optimizer wrapper around run_pcmciplus()</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_optimize_pcmciplus_alpha</span><span class="p">(</span>
                        <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
                        <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
                        <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                        <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
                        <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="n">contemp_collider_rule</span><span class="p">,</span>
                        <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span>
                        <span class="n">reset_lagged_links</span><span class="o">=</span><span class="n">reset_lagged_links</span><span class="p">,</span>
                        <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
                        <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">,</span>
                        <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
                        <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
                        <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
                        <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span>

        <span class="k">elif</span> <span class="n">pc_alpha</span> <span class="o">&lt;</span> <span class="mf">0.</span> <span class="ow">or</span> <span class="n">pc_alpha</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Choose 0 &lt;= pc_alpha &lt;= 1&quot;</span><span class="p">)</span>

        <span class="c1"># Check the limits on tau</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_check_tau_limits</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="c1"># Set the link assumption</span>
        <span class="n">_int_link_assumptions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_link_assumptions</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>


        <span class="c1">#</span>
        <span class="c1"># Phase 1: Get a superset of lagged parents from run_pc_stable</span>
        <span class="c1">#</span>
        <span class="n">lagged_parents</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_pc_stable</span><span class="p">(</span><span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
                            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
                            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
                            <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
                            <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">)</span>
        <span class="c1"># Extract p- and val-matrix</span>
        <span class="n">p_matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">p_matrix</span>
        <span class="n">val_matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_matrix</span>

        <span class="c1">#</span>
        <span class="c1"># Phase 2: PC algorithm with contemp. conditions and MCI tests</span>
        <span class="c1">#</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Step 2: PC algorithm with contemp. conditions &quot;</span>
                  <span class="s2">&quot;and MCI tests</span><span class="se">\n</span><span class="s2">##&quot;</span>
                  <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">Parameters:&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">link_assumptions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">link_assumptions = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">_int_link_assumptions</span><span class="p">))</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">independence test = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">measure</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_min = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_min</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">tau_max = </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">tau_max</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">pc_alpha = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pc_alpha</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">contemp_collider_rule = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">contemp_collider_rule</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">conflict_resolution = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">conflict_resolution</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">reset_lagged_links = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">reset_lagged_links</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_dim = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_dim</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_py = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_py</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_px = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_px</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">max_conds_px_lagged = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">max_conds_px_lagged</span>
                  <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">fdr_method = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">fdr_method</span>
                  <span class="p">)</span>

        <span class="n">skeleton_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcmciplus_mci_skeleton_phase</span><span class="p">(</span>
                            <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span> 
                            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">_int_link_assumptions</span><span class="p">,</span> 
                            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
                            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span> 
                            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> 
                            <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span> 
                            <span class="n">max_combinations</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>    <span class="c1"># Otherwise MCI step is not consistent</span>
                            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
                            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span> 
                            <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span> 
                            <span class="n">reset_lagged_links</span><span class="o">=</span><span class="n">reset_lagged_links</span><span class="p">,</span> 
                            <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">,</span>
                            <span class="n">p_matrix</span><span class="o">=</span><span class="n">p_matrix</span><span class="p">,</span> 
                            <span class="n">val_matrix</span><span class="o">=</span><span class="n">val_matrix</span><span class="p">,</span>
                            <span class="p">)</span>

        <span class="c1">#</span>
        <span class="c1"># Phase 3: Collider orientations (with MCI tests for default majority collider rule)</span>
        <span class="c1">#</span>
        <span class="n">colliders_step_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcmciplus_collider_phase</span><span class="p">(</span>
                            <span class="n">skeleton_graph</span><span class="o">=</span><span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">],</span> 
                            <span class="n">sepsets</span><span class="o">=</span><span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">],</span> 
                            <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span> 
                            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span> 
                            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span> 
                            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> 
                            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span> 
                            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span> 
                            <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
                            <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span> 
                            <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="n">contemp_collider_rule</span><span class="p">)</span>
        
        <span class="c1">#</span>
        <span class="c1"># Phase 4: Meek rule orientations</span>
        <span class="c1">#</span>
        <span class="n">final_graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcmciplus_rule_orientation_phase</span><span class="p">(</span>
                            <span class="n">collider_graph</span><span class="o">=</span><span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">],</span>
                            <span class="n">ambiguous_triples</span><span class="o">=</span><span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">],</span> 
                            <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">)</span>

        <span class="c1"># Store the parents in the pcmci member</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">all_lagged_parents</span> <span class="o">=</span> <span class="n">lagged_parents</span>

        <span class="n">return_dict</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s1">&#39;graph&#39;</span><span class="p">:</span> <span class="n">final_graph</span><span class="p">,</span>
            <span class="s1">&#39;p_matrix&#39;</span><span class="p">:</span> <span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span>
            <span class="s1">&#39;val_matrix&#39;</span><span class="p">:</span> <span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span>
            <span class="s1">&#39;sepsets&#39;</span><span class="p">:</span> <span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">],</span>
            <span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">:</span> <span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">],</span>
            <span class="p">}</span>

        <span class="c1"># No confidence interval estimation here</span>
        <span class="n">return_dict</span><span class="p">[</span><span class="s1">&#39;conf_matrix&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Print the results</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">print_results</span><span class="p">(</span><span class="n">return_dict</span><span class="p">,</span> <span class="n">alpha_level</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">)</span>
        
        <span class="c1"># Return the dictionary</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="n">return_dict</span>
        
        <span class="k">return</span> <span class="n">return_dict</span></div>

    
        <span class="c1"># # Set the maximum condition dimension for Y and X</span>
        <span class="c1"># max_conds_py = self._set_max_condition_dim(max_conds_py,</span>
        <span class="c1">#                                            tau_min, tau_max)</span>
        <span class="c1"># max_conds_px = self._set_max_condition_dim(max_conds_px,</span>
        <span class="c1">#                                            tau_min, tau_max)</span>

        <span class="c1"># if reset_lagged_links:</span>
        <span class="c1">#     # Run PCalg on full graph, ignoring that some lagged links</span>
        <span class="c1">#     # were determined as non-significant in PC1 step</span>
        <span class="c1">#     links_for_pc = deepcopy(_int_link_assumptions)</span>
        <span class="c1"># else:</span>
        <span class="c1">#     # Run PCalg only on lagged parents found with PC1 </span>
        <span class="c1">#     # plus all contemporaneous links</span>
        <span class="c1">#     links_for_pc = {}  #deepcopy(lagged_parents)</span>
        <span class="c1">#     for j in range(self.N):</span>
        <span class="c1">#         links_for_pc[j] = {}</span>
        <span class="c1">#         for parent in lagged_parents[j]:</span>
        <span class="c1">#             if _int_link_assumptions[j][parent] in [&#39;-?&gt;&#39;, &#39;--&gt;&#39;]:</span>
        <span class="c1">#                 links_for_pc[j][parent] = _int_link_assumptions[j][parent]</span>

        <span class="c1">#         # Add contemporaneous links</span>
        <span class="c1">#         for link in _int_link_assumptions[j]:</span>
        <span class="c1">#             i, tau = link</span>
        <span class="c1">#             link_type = _int_link_assumptions[j][link]</span>
        <span class="c1">#             if abs(tau) == 0:</span>
        <span class="c1">#                 links_for_pc[j][(i, 0)] = link_type</span>

        <span class="c1"># results = self.run_pcalg(</span>
        <span class="c1">#     link_assumptions=links_for_pc,</span>
        <span class="c1">#     pc_alpha=pc_alpha,</span>
        <span class="c1">#     tau_min=tau_min,</span>
        <span class="c1">#     tau_max=tau_max,</span>
        <span class="c1">#     max_conds_dim=max_conds_dim,</span>
        <span class="c1">#     max_combinations=max_combinations,</span>
        <span class="c1">#     lagged_parents=lagged_parents,</span>
        <span class="c1">#     max_conds_py=max_conds_py,</span>
        <span class="c1">#     max_conds_px=max_conds_px,</span>
        <span class="c1">#     max_conds_px_lagged=max_conds_px_lagged,</span>
        <span class="c1">#     mode=&#39;contemp_conds&#39;,</span>
        <span class="c1">#     contemp_collider_rule=contemp_collider_rule,</span>
        <span class="c1">#     conflict_resolution=conflict_resolution)</span>

        <span class="c1"># graph = results[&#39;graph&#39;]</span>

        <span class="c1"># # Update p_matrix and val_matrix with values from links_for_pc</span>
        <span class="c1"># for j in range(self.N):</span>
        <span class="c1">#     for link in links_for_pc[j]:</span>
        <span class="c1">#         i, tau = link</span>
        <span class="c1">#         if links_for_pc[j][link] not in [&#39;&lt;--&#39;, &#39;&lt;?-&#39;]:</span>
        <span class="c1">#             p_matrix[i, j, abs(tau)] = results[&#39;p_matrix&#39;][i, j, abs(tau)]</span>
        <span class="c1">#             val_matrix[i, j, abs(tau)] = results[&#39;val_matrix&#39;][i, j, </span>
        <span class="c1">#                                                                abs(tau)]</span>

        <span class="c1"># # Update p_matrix and val_matrix for indices of symmetrical links</span>
        <span class="c1"># p_matrix[:, :, 0] = results[&#39;p_matrix&#39;][:, :, 0]</span>
        <span class="c1"># val_matrix[:, :, 0] = results[&#39;val_matrix&#39;][:, :, 0]</span>

        <span class="c1"># ambiguous = results[&#39;ambiguous_triples&#39;]</span>

        <span class="c1"># conf_matrix = None</span>
        <span class="c1"># TODO: implement confidence estimation, but how?</span>
        <span class="c1"># if self.cond_ind_test.confidence is not False:</span>
        <span class="c1">#     conf_matrix = results[&#39;conf_matrix&#39;]</span>

        <span class="c1"># # Correct the p_matrix if there is a fdr_method</span>
        <span class="c1"># if fdr_method != &#39;none&#39;:</span>
        <span class="c1">#     p_matrix = self.get_corrected_pvalues(p_matrix=p_matrix, tau_min=tau_min, </span>
        <span class="c1">#                                           tau_max=tau_max, </span>
        <span class="c1">#                                           link_assumptions=_int_link_assumptions,</span>
        <span class="c1">#                                           fdr_method=fdr_method)</span>

        <span class="c1"># # Store the parents in the pcmci member</span>
        <span class="c1"># self.all_lagged_parents = lagged_parents</span>

        <span class="c1"># # p_matrix=results[&#39;p_matrix&#39;]</span>
        <span class="c1"># # val_matrix=results[&#39;val_matrix&#39;]</span>

        <span class="c1"># Cache the resulting values in the return dictionary</span>
        <span class="c1"># return_dict = {&#39;graph&#39;: graph,</span>
        <span class="c1">#                &#39;val_matrix&#39;: val_matrix,</span>
        <span class="c1">#                &#39;p_matrix&#39;: p_matrix,</span>
        <span class="c1">#                &#39;ambiguous_triples&#39;: ambiguous,</span>
        <span class="c1">#                &#39;conf_matrix&#39;: conf_matrix}</span>

        <span class="c1"># # Print the results</span>
        <span class="c1"># if self.verbosity &gt; 0:</span>
        <span class="c1">#     self.print_results(return_dict, alpha_level=pc_alpha)</span>
        <span class="c1"># # Return the dictionary</span>
        <span class="c1"># self.results = return_dict</span>
        <span class="c1"># return return_dict</span>

    <span class="k">def</span> <span class="nf">_pcmciplus_mci_skeleton_phase</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
            <span class="n">lagged_parents</span><span class="p">,</span> 
            <span class="n">link_assumptions</span><span class="p">,</span> 
            <span class="n">pc_alpha</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="p">,</span> 
            <span class="n">tau_max</span><span class="p">,</span> 
            <span class="n">max_conds_dim</span><span class="p">,</span> 
            <span class="n">max_combinations</span><span class="p">,</span> 
            <span class="n">max_conds_py</span><span class="p">,</span> 
            <span class="n">max_conds_px</span><span class="p">,</span> 
            <span class="n">max_conds_px_lagged</span><span class="p">,</span> 
            <span class="n">reset_lagged_links</span><span class="p">,</span>
            <span class="n">fdr_method</span><span class="p">,</span>
            <span class="n">p_matrix</span><span class="p">,</span> 
            <span class="n">val_matrix</span><span class="p">,</span>
            <span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;MCI Skeleton phase.&quot;&quot;&quot;</span>

        <span class="c1"># Set the maximum condition dimension for Y and X</span>
        <span class="n">max_conds_py</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_py</span><span class="p">,</span>
                                                   <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="n">max_conds_px</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_px</span><span class="p">,</span>
                                                   <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">reset_lagged_links</span><span class="p">:</span>
            <span class="c1"># Run PCalg on full graph, ignoring that some lagged links</span>
            <span class="c1"># were determined as non-significant in PC1 step</span>
            <span class="n">links_for_pc</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Run PCalg only on lagged parents found with PC1 </span>
            <span class="c1"># plus all contemporaneous links</span>
            <span class="n">links_for_pc</span> <span class="o">=</span> <span class="p">{}</span>  <span class="c1">#deepcopy(lagged_parents)</span>
            <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
                <span class="n">links_for_pc</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
                <span class="k">for</span> <span class="n">parent</span> <span class="ow">in</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                    <span class="k">if</span> <span class="n">link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">parent</span><span class="p">]</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;-?&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;--&gt;&#39;</span><span class="p">]:</span>
                        <span class="n">links_for_pc</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">parent</span><span class="p">]</span> <span class="o">=</span> <span class="n">link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">parent</span><span class="p">]</span>

                <span class="c1"># Add contemporaneous links</span>
                <span class="k">for</span> <span class="n">link</span> <span class="ow">in</span> <span class="n">link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                    <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">link</span>
                    <span class="n">link_type</span> <span class="o">=</span> <span class="n">link_assumptions</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">link</span><span class="p">]</span>
                    <span class="k">if</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                        <span class="n">links_for_pc</span><span class="p">[</span><span class="n">j</span><span class="p">][(</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">)]</span> <span class="o">=</span> <span class="n">link_type</span>


        <span class="k">if</span> <span class="n">max_conds_dim</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">max_conds_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span>

        <span class="k">if</span> <span class="n">max_combinations</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">max_combinations</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">inf</span>

        <span class="n">initial_graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dict_to_graph</span><span class="p">(</span><span class="n">links_for_pc</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>

        <span class="n">skeleton_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcalg_skeleton</span><span class="p">(</span>
            <span class="n">initial_graph</span><span class="o">=</span><span class="n">initial_graph</span><span class="p">,</span>
            <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span>
            <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;contemp_conds&#39;</span><span class="p">,</span>
            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
            <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
            <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
            <span class="p">)</span>

        <span class="c1"># Symmetrize p_matrix and val_matrix coming from skeleton</span>
        <span class="n">symmetrized_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">symmetrize_p_and_val_matrix</span><span class="p">(</span>
                            <span class="n">p_matrix</span><span class="o">=</span><span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span> 
                            <span class="n">val_matrix</span><span class="o">=</span><span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span> 
                            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">links_for_pc</span><span class="p">,</span>
                            <span class="n">conf_matrix</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>

        <span class="c1"># Update p_matrix and val_matrix with values from skeleton phase</span>
        <span class="c1"># Contemporaneous entries (not filled in run_pc_stable lagged phase)</span>
        <span class="n">p_matrix</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">][:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span>
        <span class="n">val_matrix</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">][:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span>

        <span class="c1"># Update all entries computed in the MCI step </span>
        <span class="c1"># (these are in links_for_pc); values for entries</span>
        <span class="c1"># that were removed in the lagged-condition phase are kept from before</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">link</span> <span class="ow">in</span> <span class="n">links_for_pc</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="o">=</span> <span class="n">link</span>
                <span class="k">if</span> <span class="n">links_for_pc</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">link</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;&lt;--&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;?-&#39;</span><span class="p">]:</span>
                    <span class="n">p_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">][</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span>
                    <span class="n">val_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span> <span class="o">=</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">][</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> 
                                                                 <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">)]</span>

        <span class="c1"># Optionally correct the p_matrix</span>
        <span class="k">if</span> <span class="n">fdr_method</span> <span class="o">!=</span> <span class="s1">&#39;none&#39;</span><span class="p">:</span>
            <span class="n">p_matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_corrected_pvalues</span><span class="p">(</span><span class="n">p_matrix</span><span class="o">=</span><span class="n">p_matrix</span><span class="p">,</span> <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span> 
                                                  <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> 
                                                  <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
                                                  <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span>

        <span class="c1"># Update matrices</span>
        <span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">p_matrix</span>
        <span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">val_matrix</span>

        <span class="k">return</span> <span class="n">skeleton_results</span>


    <span class="k">def</span> <span class="nf">_pcmciplus_collider_phase</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">skeleton_graph</span><span class="p">,</span> <span class="n">sepsets</span><span class="p">,</span> <span class="n">lagged_parents</span><span class="p">,</span>
        <span class="n">pc_alpha</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">max_conds_py</span><span class="p">,</span> <span class="n">max_conds_px</span><span class="p">,</span> <span class="n">max_conds_px_lagged</span><span class="p">,</span>
        <span class="n">conflict_resolution</span><span class="p">,</span> <span class="n">contemp_collider_rule</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;MCI collider phase.&quot;&quot;&quot;</span>    

        <span class="c1"># Set the maximum condition dimension for Y and X</span>
        <span class="n">max_conds_py</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_py</span><span class="p">,</span>
                                                   <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="n">max_conds_px</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_px</span><span class="p">,</span>
                                                   <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="c1"># Now change assumed links marks</span>
        <span class="n">skeleton_graph</span><span class="p">[</span><span class="n">skeleton_graph</span><span class="o">==</span><span class="s1">&#39;o?o&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;o-o&#39;</span>
        <span class="n">skeleton_graph</span><span class="p">[</span><span class="n">skeleton_graph</span><span class="o">==</span><span class="s1">&#39;-?&gt;&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;--&gt;&#39;</span>
        <span class="n">skeleton_graph</span><span class="p">[</span><span class="n">skeleton_graph</span><span class="o">==</span><span class="s1">&#39;&lt;?-&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&lt;--&#39;</span>

        <span class="n">colliders_step_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcalg_colliders</span><span class="p">(</span>
            <span class="n">graph</span><span class="o">=</span><span class="n">skeleton_graph</span><span class="p">,</span>
            <span class="n">sepsets</span><span class="o">=</span><span class="n">sepsets</span><span class="p">,</span>
            <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span>
            <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;contemp_conds&#39;</span><span class="p">,</span>
            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
            <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
            <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span>
            <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="n">contemp_collider_rule</span><span class="p">,</span>
            <span class="p">)</span>

        <span class="k">return</span> <span class="n">colliders_step_results</span>

    <span class="k">def</span> <span class="nf">_pcmciplus_rule_orientation_phase</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">collider_graph</span><span class="p">,</span>
         <span class="n">ambiguous_triples</span><span class="p">,</span> <span class="n">conflict_resolution</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;MCI rule orientation phase.&quot;&quot;&quot;</span>  

        <span class="n">final_graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcalg_rules_timeseries</span><span class="p">(</span>
            <span class="n">graph</span><span class="o">=</span><span class="n">collider_graph</span><span class="p">,</span>
            <span class="n">ambiguous_triples</span><span class="o">=</span><span class="n">ambiguous_triples</span><span class="p">,</span>
            <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span>
            <span class="p">)</span>

        <span class="k">return</span> <span class="n">final_graph</span>


<div class="viewcode-block" id="PCMCI.run_pcalg"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_pcalg">[docs]</a>    <span class="k">def</span> <span class="nf">run_pcalg</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> 
                    <span class="n">selected_links</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                    <span class="n">link_assumptions</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                    <span class="n">pc_alpha</span><span class="o">=</span><span class="mf">0.01</span><span class="p">,</span> 
                    <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
                    <span class="n">tau_max</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> 
                    <span class="n">max_conds_dim</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                    <span class="n">max_combinations</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                    <span class="n">lagged_parents</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                    <span class="n">max_conds_py</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                    <span class="n">max_conds_px</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                    <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                    <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;standard&#39;</span><span class="p">,</span> 
                    <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="s1">&#39;majority&#39;</span><span class="p">,</span>
                    <span class="n">conflict_resolution</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>

<span class="w">        </span><span class="sd">&quot;&quot;&quot;Runs PC algorithm for time-lagged and contemporaneous causal</span>
<span class="sd">        discovery for time series.</span>

<span class="sd">        For ``mode=&#39;contemp_conds&#39;`` this implements Steps 2-4 of the</span>
<span class="sd">        PCMCIplus method described in [5]. For ``mode=&#39;standard&#39;`` this</span>
<span class="sd">        implements the standard PC algorithm adapted to time series.</span>

<span class="sd">        [5] J. Runge, Discovering contemporaneous and lagged causal relations</span>
<span class="sd">        in autocorrelated nonlinear time series datasets</span>
<span class="sd">        http://www.auai.org/~w-auai/uai2020/proceedings/579_main_paper.pdf</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        selected_links : dict or None</span>
<span class="sd">            Deprecated, replaced by link_assumptions</span>
<span class="sd">        link_assumptions : dict</span>
<span class="sd">            Dictionary of form {j:{(i, -tau): link_type, ...}, ...} specifying</span>
<span class="sd">            assumptions about links. This initializes the graph with entries</span>
<span class="sd">            graph[i,j,tau] = link_type. For example, graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            implies that a directed link from i to j at lag 0 must exist.</span>
<span class="sd">            Valid link types are &#39;o-o&#39;, &#39;--&gt;&#39;, &#39;&lt;--&#39;. In addition, the middle</span>
<span class="sd">            mark can be &#39;?&#39; instead of &#39;-&#39;. Then &#39;-?&gt;&#39; implies that this link</span>
<span class="sd">            may not exist, but if it exists, its orientation is &#39;--&gt;&#39;. Link</span>
<span class="sd">            assumptions need to be consistent, i.e., graph[i,j,0] = &#39;--&gt;&#39;</span>
<span class="sd">            requires graph[j,i,0] = &#39;&lt;--&#39; and acyclicity must hold. If a link</span>
<span class="sd">            does not appear in the dictionary, it is assumed absent. That is,</span>
<span class="sd">            if link_assumptions is not None, then all links have to be specified</span>
<span class="sd">            or the links are assumed absent.</span>
<span class="sd">        lagged_parents : dictionary</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...} containing</span>
<span class="sd">            additional conditions for each CI test. As part of PCMCIplus</span>
<span class="sd">            these are the superset of lagged parents estimated with the PC1</span>
<span class="sd">            algorithm.</span>
<span class="sd">        mode : {&#39;standard&#39;, &#39;contemp_conds&#39;}</span>
<span class="sd">            For ``mode=&#39;contemp_conds&#39;`` this implements Steps 2-4 of the</span>
<span class="sd">            PCMCIplus method. For ``mode=&#39;standard&#39;`` this implements the</span>
<span class="sd">            standard PC algorithm adapted to time series.</span>
<span class="sd">        tau_min : int, optional (default: 0)</span>
<span class="sd">            Minimum time lag to test.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        pc_alpha : float, optional (default: 0.01)</span>
<span class="sd">            Significance level.</span>
<span class="sd">        contemp_collider_rule : {&#39;majority&#39;, &#39;conservative&#39;, &#39;none&#39;}</span>
<span class="sd">            Rule for collider phase to use. See the paper for details. Only</span>
<span class="sd">            &#39;majority&#39; and &#39;conservative&#39; lead to an order-independent</span>
<span class="sd">            algorithm.</span>
<span class="sd">        conflict_resolution : bool, optional (default: True)</span>
<span class="sd">            Whether to mark conflicts in orientation rules. Only for True</span>
<span class="sd">            this leads to an order-independent algorithm.</span>
<span class="sd">        max_conds_dim : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test. Must be infinite (default for max_combinations=1) for consistency.</span>
<span class="sd">        max_conds_py : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of Y to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px_lagged : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X when X is lagged in MCI </span>
<span class="sd">            tests. If None is passed, this number is equal to max_conds_px.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Resulting causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values regarding adjacencies.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values regarding adjacencies.</span>
<span class="sd">        sepsets : dictionary</span>
<span class="sd">            Separating sets. See paper for details.</span>
<span class="sd">        ambiguous_triples : list</span>
<span class="sd">            List of ambiguous triples, only relevant for &#39;majority&#39; and</span>
<span class="sd">            &#39;conservative&#39; rules, see paper for details.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># TODO: save_iterations</span>

        <span class="k">if</span> <span class="n">selected_links</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;selected_links is DEPRECATED, use link_assumptions instead.&quot;</span><span class="p">)</span>

        <span class="c1"># Sanity checks</span>
        <span class="k">if</span> <span class="n">pc_alpha</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;pc_alpha=None not supported in PC algorithm, &quot;</span>
                             <span class="s2">&quot;choose 0 &lt; pc_alpha &lt; 1 (e.g., 0.01)&quot;</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">mode</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;contemp_conds&#39;</span><span class="p">,</span> <span class="s1">&#39;standard&#39;</span><span class="p">]:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;mode must be either &#39;contemp_conds&#39; or &quot;</span>
                             <span class="s2">&quot;&#39;standard&#39;&quot;</span><span class="p">)</span>

        <span class="c1"># Check the limits on tau</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_check_tau_limits</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
        <span class="c1"># Set the selected links</span>
        <span class="c1"># _int_sel_links = self._set_sel_links(selected_links, tau_min, tau_max)</span>
        <span class="n">_int_link_assumptions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_link_assumptions</span><span class="p">(</span><span class="n">link_assumptions</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">max_conds_dim</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;standard&#39;</span><span class="p">:</span>
                <span class="n">max_conds_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_max_condition_dim</span><span class="p">(</span><span class="n">max_conds_dim</span><span class="p">,</span>
                                                            <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;contemp_conds&#39;</span><span class="p">:</span>
                <span class="n">max_conds_dim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span>

        <span class="k">if</span> <span class="n">max_combinations</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">max_combinations</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">inf</span>

        <span class="n">initial_graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dict_to_graph</span><span class="p">(</span><span class="n">_int_link_assumptions</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">)</span>

        <span class="n">skeleton_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcalg_skeleton</span><span class="p">(</span>
            <span class="n">initial_graph</span><span class="o">=</span><span class="n">initial_graph</span><span class="p">,</span>
            <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span>
            <span class="n">mode</span><span class="o">=</span><span class="n">mode</span><span class="p">,</span>
            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
            <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
            <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
            <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="n">skeleton_graph</span> <span class="o">=</span> <span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">]</span>
        <span class="n">sepsets</span> <span class="o">=</span> <span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">]</span>

        <span class="c1"># Now change assumed links marks</span>
        <span class="n">skeleton_graph</span><span class="p">[</span><span class="n">skeleton_graph</span><span class="o">==</span><span class="s1">&#39;o?o&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;o-o&#39;</span>
        <span class="n">skeleton_graph</span><span class="p">[</span><span class="n">skeleton_graph</span><span class="o">==</span><span class="s1">&#39;-?&gt;&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;--&gt;&#39;</span>
        <span class="n">skeleton_graph</span><span class="p">[</span><span class="n">skeleton_graph</span><span class="o">==</span><span class="s1">&#39;&lt;?-&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&lt;--&#39;</span>

        <span class="n">colliders_step_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcalg_colliders</span><span class="p">(</span>
            <span class="n">graph</span><span class="o">=</span><span class="n">skeleton_graph</span><span class="p">,</span>
            <span class="n">sepsets</span><span class="o">=</span><span class="n">sepsets</span><span class="p">,</span>
            <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span>
            <span class="n">mode</span><span class="o">=</span><span class="n">mode</span><span class="p">,</span>
            <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span>
            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
            <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
            <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span>
            <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="n">contemp_collider_rule</span><span class="p">,</span>
            <span class="p">)</span>

        <span class="n">collider_graph</span> <span class="o">=</span> <span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">]</span>
        <span class="n">ambiguous_triples</span> <span class="o">=</span> <span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">]</span>

        <span class="n">final_graph</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pcalg_rules_timeseries</span><span class="p">(</span>
            <span class="n">graph</span><span class="o">=</span><span class="n">collider_graph</span><span class="p">,</span>
            <span class="n">ambiguous_triples</span><span class="o">=</span><span class="n">ambiguous_triples</span><span class="p">,</span>
            <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="c1"># Symmetrize p_matrix and val_matrix</span>
        <span class="n">symmetrized_results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">symmetrize_p_and_val_matrix</span><span class="p">(</span>
                            <span class="n">p_matrix</span><span class="o">=</span><span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span> 
                            <span class="n">val_matrix</span><span class="o">=</span><span class="n">skeleton_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span> 
                            <span class="n">link_assumptions</span><span class="o">=</span><span class="n">_int_link_assumptions</span><span class="p">,</span>
                            <span class="n">conf_matrix</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>

        <span class="c1"># Convert numerical graph matrix to string</span>
        <span class="n">graph_str</span> <span class="o">=</span> <span class="n">final_graph</span> <span class="c1"># self.convert_to_string_graph(final_graph)</span>

        <span class="n">pc_results</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s1">&#39;graph&#39;</span><span class="p">:</span> <span class="n">graph_str</span><span class="p">,</span>
            <span class="s1">&#39;p_matrix&#39;</span><span class="p">:</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">],</span>
            <span class="s1">&#39;val_matrix&#39;</span><span class="p">:</span> <span class="n">symmetrized_results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">],</span>
            <span class="s1">&#39;sepsets&#39;</span><span class="p">:</span> <span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">],</span>
            <span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">:</span> <span class="n">colliders_step_results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">],</span>
        <span class="p">}</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">-----------------------------&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;PCMCIplus algorithm finished.&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;-----------------------------&quot;</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">pc_results</span> <span class="o">=</span> <span class="n">pc_results</span>
        <span class="k">return</span> <span class="n">pc_results</span></div>

<div class="viewcode-block" id="PCMCI.run_pcalg_non_timeseries_data"><a class="viewcode-back" href="../../index.html#tigramite.pcmci.PCMCI.run_pcalg_non_timeseries_data">[docs]</a>    <span class="k">def</span> <span class="nf">run_pcalg_non_timeseries_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pc_alpha</span><span class="o">=</span><span class="mf">0.01</span><span class="p">,</span>
                  <span class="n">max_conds_dim</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">max_combinations</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> 
                  <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="s1">&#39;majority&#39;</span><span class="p">,</span>
                  <span class="n">conflict_resolution</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>

<span class="w">        </span><span class="sd">&quot;&quot;&quot;Runs PC algorithm for non-time series data.</span>

<span class="sd">        Simply calls run_pcalg with tau_min = tau_max = 0.</span>
<span class="sd">        Removes lags from output dictionaries.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        pc_alpha : float, optional (default: 0.01)</span>
<span class="sd">            Significance level.</span>
<span class="sd">        contemp_collider_rule : {&#39;majority&#39;, &#39;conservative&#39;, &#39;none&#39;}</span>
<span class="sd">            Rule for collider phase to use. See the paper for details. Only</span>
<span class="sd">            &#39;majority&#39; and &#39;conservative&#39; lead to an order-independent</span>
<span class="sd">            algorithm.</span>
<span class="sd">        conflict_resolution : bool, optional (default: True)</span>
<span class="sd">            Whether to mark conflicts in orientation rules. Only for True</span>
<span class="sd">            this leads to an order-independent algorithm.</span>
<span class="sd">        max_conds_dim : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test. Must be infinite (default for max_combinations=1) for consistency.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, 1]</span>
<span class="sd">            Resulting causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, 1]</span>
<span class="sd">            Estimated matrix of test statistic values regarding adjacencies.</span>
<span class="sd">        p_matrix : array of shape [N, N, 1]</span>
<span class="sd">            Estimated matrix of p-values regarding adjacencies.</span>
<span class="sd">        sepsets : dictionary</span>
<span class="sd">            Separating sets. See paper for details.</span>
<span class="sd">        ambiguous_triples : list</span>
<span class="sd">            List of ambiguous triples, only relevant for &#39;majority&#39; and</span>
<span class="sd">            &#39;conservative&#39; rules, see paper for details.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_pcalg</span><span class="p">(</span><span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">,</span> <span class="n">tau_min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> 
                    <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span> <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">,</span>
                  <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;standard&#39;</span><span class="p">,</span> <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="n">contemp_collider_rule</span><span class="p">,</span>
                  <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">)</span>

        <span class="c1"># Remove tau-dimension</span>
        <span class="n">old_sepsets</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
        <span class="n">results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">old_sepset</span> <span class="ow">in</span> <span class="n">old_sepsets</span><span class="p">:</span>
           <span class="n">new_sepset</span> <span class="o">=</span> <span class="p">(</span><span class="n">old_sepset</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">old_sepset</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
           <span class="n">conds</span> <span class="o">=</span> <span class="p">[</span><span class="n">cond</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">cond</span> <span class="ow">in</span> <span class="n">old_sepsets</span><span class="p">[</span><span class="n">old_sepset</span><span class="p">]]</span>

           <span class="n">results</span><span class="p">[</span><span class="s1">&#39;sepsets&#39;</span><span class="p">][</span><span class="n">new_sepset</span><span class="p">]</span> <span class="o">=</span> <span class="n">conds</span>

        <span class="n">ambiguous_triples</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
        <span class="n">results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">triple</span> <span class="ow">in</span> <span class="n">ambiguous_triples</span><span class="p">:</span>
           <span class="n">new_triple</span> <span class="o">=</span> <span class="p">(</span><span class="n">triple</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">triple</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">triple</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>

           <span class="n">results</span><span class="p">[</span><span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_triple</span><span class="p">)</span>
        
        <span class="bp">self</span><span class="o">.</span><span class="n">pc_results</span> <span class="o">=</span> <span class="n">results</span>
        <span class="k">return</span> <span class="n">results</span></div>


    <span class="k">def</span> <span class="nf">_run_pcalg_test</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">abstau</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">S</span><span class="p">,</span> <span class="n">lagged_parents</span><span class="p">,</span> <span class="n">max_conds_py</span><span class="p">,</span>
                        <span class="n">max_conds_px</span><span class="p">,</span> <span class="n">max_conds_px_lagged</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">alpha_or_thres</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;MCI conditional independence tests within PCMCIplus or PC algorithm.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array</span>
<span class="sd">            ...</span>
<span class="sd">        i : int</span>
<span class="sd">            Variable index.</span>
<span class="sd">        abstau : int</span>
<span class="sd">            Time lag (absolute value).</span>
<span class="sd">        j : int</span>
<span class="sd">            Variable index.</span>
<span class="sd">        S : list</span>
<span class="sd">            List of contemporaneous conditions.</span>
<span class="sd">        lagged_parents : dictionary of lists</span>
<span class="sd">            Dictionary of lagged parents for each node.</span>
<span class="sd">        max_conds_py : int</span>
<span class="sd">            Max number of lagged parents for node j.</span>
<span class="sd">        max_conds_px : int</span>
<span class="sd">            Max number of lagged parents for lagged node i.</span>
<span class="sd">        max_conds_px_lagged : int</span>
<span class="sd">            Maximum number of lagged conditions of X when X is lagged in MCI </span>
<span class="sd">            tests. If None is passed, this number is equal to max_conds_px.</span>
<span class="sd">        tau_max : int</span>
<span class="sd">            Maximum time lag.</span>
<span class="sd">        alpha_or_thres : float</span>
<span class="sd">            Significance level (if significance=&#39;analytic&#39; or &#39;shuffle_test&#39;) or</span>
<span class="sd">            threshold (if significance=&#39;fixed_thres&#39;). If given, run_test returns</span>
<span class="sd">            the test decision dependent=True/False.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        val, pval, Z, [dependent] : Tuple of floats, list, and bool</span>
<span class="sd">            The test statistic value and the p-value and list of conditions. If alpha_or_thres is</span>
<span class="sd">            given, run_test also returns the test decision dependent=True/False.             </span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="c1"># Perform independence test adding lagged parents</span>
        <span class="k">if</span> <span class="n">lagged_parents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">conds_y</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">j</span><span class="p">][:</span><span class="n">max_conds_py</span><span class="p">]</span>
            <span class="c1"># Get the conditions for node i</span>
            <span class="k">if</span> <span class="n">abstau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">conds_x</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px</span><span class="p">]</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">max_conds_px_lagged</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="n">conds_x</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px</span><span class="p">]</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">conds_x</span> <span class="o">=</span> <span class="n">lagged_parents</span><span class="p">[</span><span class="n">i</span><span class="p">][:</span><span class="n">max_conds_px_lagged</span><span class="p">]</span>

        <span class="k">else</span><span class="p">:</span>
            <span class="n">conds_y</span> <span class="o">=</span> <span class="n">conds_x</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="c1"># Shift the conditions for X by tau</span>
        <span class="n">conds_x_lagged</span> <span class="o">=</span> <span class="p">[(</span><span class="n">k</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span> <span class="o">+</span> <span class="n">k_tau</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">k_tau</span> <span class="ow">in</span> <span class="n">conds_x</span><span class="p">]</span>

        <span class="n">Z</span> <span class="o">=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">S</span><span class="p">]</span>
        <span class="n">Z</span> <span class="o">+=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">conds_y</span> <span class="k">if</span>
              <span class="n">node</span> <span class="o">!=</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">]</span>
        <span class="c1"># Remove overlapping nodes between conds_x_lagged and conds_y</span>
        <span class="n">Z</span> <span class="o">+=</span> <span class="p">[</span><span class="n">node</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">conds_x_lagged</span> <span class="k">if</span> <span class="n">node</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">Z</span><span class="p">]</span>

        <span class="c1"># If middle mark is &#39;-&#39;, then set pval=0</span>
        <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">abstau</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span> <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">abstau</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;-&#39;</span><span class="p">:</span>
            <span class="n">val</span> <span class="o">=</span> <span class="mf">1.</span> 
            <span class="n">pval</span> <span class="o">=</span> <span class="mf">0.</span>
            <span class="n">dependent</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">dependent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">run_test</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="p">[(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)],</span> <span class="n">Y</span><span class="o">=</span><span class="p">[(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span>
                                                <span class="n">Z</span><span class="o">=</span><span class="n">Z</span><span class="p">,</span> <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                                                <span class="n">alpha_or_thres</span><span class="o">=</span><span class="n">alpha_or_thres</span><span class="p">,</span>
                                                <span class="c1"># verbosity=self.verbosity</span>
                                                <span class="p">)</span>

        <span class="k">return</span> <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">Z</span><span class="p">,</span> <span class="n">dependent</span>

    <span class="k">def</span> <span class="nf">_print_triple_info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">triple</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="n">n_triples</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Print info about the current triple being tested.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        triple : tuple</span>
<span class="sd">            Standard ((i, tau), k, j) tuple of nodes and time delays.</span>
<span class="sd">        index : int</span>
<span class="sd">            Index of triple.</span>
<span class="sd">        n_triples : int</span>
<span class="sd">            Total number of triples.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">triple</span>
        <span class="n">link_marker</span> <span class="o">=</span> <span class="p">{</span><span class="kc">True</span><span class="p">:</span><span class="s2">&quot;o-o&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span><span class="s2">&quot;--&gt;&quot;</span><span class="p">}</span>

        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Triple (</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%d</span><span class="s2">/</span><span class="si">%d</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">tau</span><span class="p">,</span> <span class="n">link_marker</span><span class="p">[</span><span class="n">tau</span><span class="o">==</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">n_triples</span><span class="p">))</span>


    <span class="k">def</span> <span class="nf">_tests_remaining</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">p</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function returning whether a certain pair still needs to be</span>
<span class="sd">        tested.&quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span>
            <span class="p">[</span><span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="k">if</span> <span class="n">a</span> <span class="o">!=</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)])</span> <span class="o">&gt;=</span> <span class="n">p</span>

    <span class="k">def</span> <span class="nf">_any_tests_remaining</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">p</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function returning whether any pair still needs to be</span>
<span class="sd">        tested.&quot;&quot;&quot;</span>
        <span class="n">remaining_pairs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remaining_pairs</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span>
                                                <span class="n">p</span><span class="p">)</span>

        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">remaining_pairs</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">True</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span>

    <span class="k">def</span> <span class="nf">_remaining_pairs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span> <span class="n">p</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Helper function returning the remaining pairs that still need to be</span>
<span class="sd">        tested.&quot;&quot;&quot;</span>
        <span class="n">N</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">pairs</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">product</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">),</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">)):</span>
            <span class="k">for</span> <span class="n">abstau</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span>
                        <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span>
                            <span class="p">[</span><span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="k">if</span> <span class="n">a</span> <span class="o">!=</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)])</span> <span class="o">&gt;=</span> <span class="n">p</span><span class="p">):</span>
                    <span class="n">pairs</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">))</span>

        <span class="k">return</span> <span class="n">pairs</span>

    <span class="k">def</span> <span class="nf">_pcalg_skeleton</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                       <span class="n">initial_graph</span><span class="p">,</span>
                       <span class="n">lagged_parents</span><span class="p">,</span>
                       <span class="n">mode</span><span class="p">,</span>
                       <span class="n">pc_alpha</span><span class="p">,</span>
                       <span class="n">tau_min</span><span class="p">,</span>
                       <span class="n">tau_max</span><span class="p">,</span>
                       <span class="n">max_conds_dim</span><span class="p">,</span>
                       <span class="n">max_combinations</span><span class="p">,</span>
                       <span class="n">max_conds_py</span><span class="p">,</span>
                       <span class="n">max_conds_px</span><span class="p">,</span>
                       <span class="n">max_conds_px_lagged</span><span class="p">,</span>
                       <span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Implements the skeleton discovery step of the PC algorithm for</span>
<span class="sd">        time series.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        initial_graph : array of shape (N, N, tau_max+1) or None</span>
<span class="sd">            Initial graph.</span>
<span class="sd">        lagged_parents : dictionary</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...} containing</span>
<span class="sd">            additional conditions for each CI test. As part of PCMCIplus</span>
<span class="sd">            these are the superset of lagged parents estimated with the PC1</span>
<span class="sd">            algorithm.</span>
<span class="sd">        mode : {&#39;standard&#39;, &#39;contemp_conds&#39;}</span>
<span class="sd">            For ``mode=&#39;contemp_conds&#39;`` this implements Steps 2-4 of the</span>
<span class="sd">            PCMCIplus method. For ``mode=&#39;standard&#39;`` this implements the</span>
<span class="sd">            standard PC algorithm adapted to time series.</span>
<span class="sd">        tau_min : int, optional (default: 0)</span>
<span class="sd">            Minimum time lag to test.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        pc_alpha : float, optional (default: 0.01)</span>
<span class="sd">            Significance level.</span>
<span class="sd">        max_conds_dim : int, optional (default: None)</span>
<span class="sd">            Maximum number of conditions to test. If None is passed, this number</span>
<span class="sd">            is unrestricted.</span>
<span class="sd">        max_combinations : int</span>
<span class="sd">            Maximum number of combinations of conditions of current cardinality</span>
<span class="sd">            to test. Must be infinite (default for max_combinations=1) for consistency.</span>
<span class="sd">        max_conds_py : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of Y to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px_lagged : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X when X is lagged in MCI </span>
<span class="sd">            tests. If None is passed, this number is equal to max_conds_px.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Resulting causal graph, see description above for interpretation.</span>
<span class="sd">        val_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of test statistic values regarding adjacencies.</span>
<span class="sd">        p_matrix : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Estimated matrix of p-values regarding adjacencies.</span>
<span class="sd">        sepsets : dictionary</span>
<span class="sd">            Separating sets. See paper for details.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">N</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">N</span>

        <span class="c1"># Form complete graph</span>
        <span class="k">if</span> <span class="n">initial_graph</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">graph</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="s1">&#39;&lt;U3&#39;</span><span class="p">)</span>
            <span class="n">graph</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;o?o&quot;</span>
            <span class="n">graph</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">:]</span> <span class="o">=</span> <span class="s2">&quot;-?&gt;&quot;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">graph</span> <span class="o">=</span> <span class="n">initial_graph</span>

        <span class="c1"># Remove lag-zero self-loops</span>
        <span class="n">graph</span><span class="p">[</span><span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">),</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">),</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>

        <span class="c1"># Define adjacencies for standard and contemp_conds mode</span>
        <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;contemp_conds&#39;</span><span class="p">:</span>
            <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series_contemp</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
        <span class="k">elif</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;standard&#39;</span><span class="p">:</span>
            <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>

        <span class="n">val_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
        
        <span class="n">val_min</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="n">val_min</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">{(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="o">-</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> <span class="n">np</span><span class="o">.</span><span class="n">inf</span>
                          <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">graph</span><span class="p">[:,</span> <span class="n">j</span><span class="p">,</span> <span class="p">:]</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">))}</span>

        <span class="c1"># Initialize p-values. Set to 1 if there&#39;s no link in the initial graph</span>
        <span class="n">p_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">N</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
        <span class="n">p_matrix</span><span class="p">[</span><span class="n">graph</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="mf">1.</span>

        <span class="n">pval_max</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
            <span class="n">pval_max</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">{(</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="o">-</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> <span class="mf">0.</span>
                           <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">graph</span><span class="p">[:,</span> <span class="n">j</span><span class="p">,</span> <span class="p">:]</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">))}</span>

        <span class="c1"># TODO: Remove sepsets alltogether?</span>
        <span class="c1"># Intialize sepsets that store the conditions that make i and j</span>
        <span class="c1"># independent</span>
        <span class="n">sepsets</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_sepsets</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">--------------------------&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Skeleton discovery phase&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;--------------------------&quot;</span><span class="p">)</span>

        <span class="c1"># Start with zero cardinality conditions</span>
        <span class="n">p</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">while</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_any_tests_remaining</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span>
                                         <span class="n">p</span><span class="p">)</span> <span class="ow">and</span> <span class="n">p</span> <span class="o">&lt;=</span> <span class="n">max_conds_dim</span><span class="p">):</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span>
                    <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Testing contemporaneous condition sets of dimension &quot;</span>
                    <span class="s2">&quot;</span><span class="si">%d</span><span class="s2">: &quot;</span> <span class="o">%</span> <span class="n">p</span><span class="p">)</span>

            <span class="n">remaining_pairs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remaining_pairs</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span>
                                                    <span class="n">tau_max</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
            <span class="n">n_remaining</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">remaining_pairs</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">ir</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">remaining_pairs</span><span class="p">):</span>
                <span class="c1"># Check if link was not already removed (contemp links)</span>
                <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">_print_link_info</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="n">j</span><span class="p">,</span> <span class="n">index_parent</span><span class="o">=</span><span class="n">ir</span><span class="p">,</span>
                                              <span class="n">parent</span><span class="o">=</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">),</span>
                                              <span class="n">num_parents</span><span class="o">=</span><span class="n">n_remaining</span><span class="p">)</span>

                    <span class="c1"># Generate all subsets of conditions of cardinality p</span>
                    <span class="n">conditions</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">(</span>
                        <span class="p">[(</span><span class="n">k</span><span class="p">,</span> <span class="n">tauk</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">tauk</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>
                         <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">k</span> <span class="o">==</span> <span class="n">i</span> <span class="ow">and</span> <span class="n">tauk</span> <span class="o">==</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)],</span> <span class="n">p</span><span class="p">))</span>

                    <span class="n">n_conditions</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">conditions</span><span class="p">)</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="nb">print</span><span class="p">(</span>
                            <span class="s2">&quot;    Iterate through </span><span class="si">%d</span><span class="s2"> subset(s) of conditions: &quot;</span>
                            <span class="o">%</span> <span class="n">n_conditions</span><span class="p">)</span>
                        <span class="k">if</span> <span class="n">lagged_parents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                            <span class="bp">self</span><span class="o">.</span><span class="n">_print_pcmciplus_conditions</span><span class="p">(</span><span class="n">lagged_parents</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span>
                                                         <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">,</span>
                                                         <span class="n">max_conds_py</span><span class="p">,</span>
                                                         <span class="n">max_conds_px</span><span class="p">,</span>
                                                         <span class="n">max_conds_px_lagged</span><span class="p">)</span>
                    <span class="n">nonsig</span> <span class="o">=</span> <span class="kc">False</span>
                    <span class="c1"># Iterate through condition sets</span>
                    <span class="k">for</span> <span class="n">q</span><span class="p">,</span> <span class="n">S</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">conditions</span><span class="p">):</span>
                        <span class="k">if</span> <span class="n">q</span> <span class="o">&gt;</span> <span class="n">max_combinations</span><span class="p">:</span>
                            <span class="k">break</span>

                        <span class="c1"># Run MCI test</span>
                        <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">Z</span><span class="p">,</span> <span class="n">dependent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_pcalg_test</span><span class="p">(</span><span class="n">graph</span><span class="o">=</span><span class="n">graph</span><span class="p">,</span>
                            <span class="n">i</span><span class="o">=</span><span class="n">i</span><span class="p">,</span> <span class="n">abstau</span><span class="o">=</span><span class="n">abstau</span><span class="p">,</span> <span class="n">j</span><span class="o">=</span><span class="n">j</span><span class="p">,</span> <span class="n">S</span><span class="o">=</span><span class="n">S</span><span class="p">,</span> <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span> 
                            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
                            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span> <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
                            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> <span class="n">alpha_or_thres</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">)</span>

                        <span class="c1"># Store minimum test statistic value for sorting adjt</span>
                        <span class="c1"># (only internally used)</span>
                        <span class="n">val_min</span><span class="p">[</span><span class="n">j</span><span class="p">][(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val</span><span class="p">),</span>
                                                       <span class="n">val_min</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
                                                           <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)))</span>
                        <span class="c1"># Store maximum p-value (only internally used)</span>
                        <span class="n">pval_max</span><span class="p">[</span><span class="n">j</span><span class="p">][(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">pval</span><span class="p">,</span>
                                                        <span class="n">pval_max</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
                                                            <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">)))</span>

                        <span class="c1"># Store max. p-value and corresponding value to return</span>
                        <span class="k">if</span> <span class="n">pval</span> <span class="o">&gt;=</span> <span class="n">p_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]:</span>
                            <span class="n">p_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]</span> <span class="o">=</span> <span class="n">pval</span>
                            <span class="n">val_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span>

                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="bp">self</span><span class="o">.</span><span class="n">_print_cond_info</span><span class="p">(</span><span class="n">Z</span><span class="o">=</span><span class="n">S</span><span class="p">,</span> <span class="n">comb_index</span><span class="o">=</span><span class="n">q</span><span class="p">,</span> <span class="n">pval</span><span class="o">=</span><span class="n">pval</span><span class="p">,</span>
                                                  <span class="n">val</span><span class="o">=</span><span class="n">val</span><span class="p">)</span>

                        <span class="c1"># If conditional independence is found, remove link</span>
                        <span class="c1"># from graph and store sepsets</span>
                        <span class="k">if</span> <span class="ow">not</span> <span class="n">dependent</span><span class="p">:</span> <span class="c1"># pval &gt; pc_alpha:</span>
                            <span class="n">nonsig</span> <span class="o">=</span> <span class="kc">True</span>
                            <span class="k">if</span> <span class="n">abstau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
                                <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">j</span><span class="p">)]</span> <span class="o">=</span> <span class="n">sepsets</span><span class="p">[</span>
                                    <span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">i</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">S</span><span class="p">)</span>
                                <span class="c1"># Also store p-value in other contemp. entry</span>
                                <span class="n">p_matrix</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">p_matrix</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
                            <span class="k">else</span><span class="p">:</span>
                                <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">abstau</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
                                <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">S</span><span class="p">)</span>
                            <span class="k">break</span>

                    <span class="c1"># Print the results if needed</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">_print_a_pc_result</span><span class="p">(</span><span class="n">nonsig</span><span class="p">,</span>
                                                <span class="n">conds_dim</span><span class="o">=</span><span class="n">p</span><span class="p">,</span>
                                                <span class="n">max_combinations</span><span class="o">=</span>
                                                <span class="n">max_combinations</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_print_link_info</span><span class="p">(</span><span class="n">j</span><span class="o">=</span><span class="n">j</span><span class="p">,</span> <span class="n">index_parent</span><span class="o">=</span><span class="n">ir</span><span class="p">,</span>
                                          <span class="n">parent</span><span class="o">=</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">abstau</span><span class="p">),</span>
                                          <span class="n">num_parents</span><span class="o">=</span><span class="n">n_remaining</span><span class="p">,</span>
                                          <span class="n">already_removed</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

            <span class="c1"># Increase condition cardinality</span>
            <span class="n">p</span> <span class="o">+=</span> <span class="mi">1</span>

            <span class="c1"># Re-compute adj and sort by minimum absolute test statistic value</span>
            <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;contemp_conds&#39;</span><span class="p">:</span>
                <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series_contemp</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">sort_by</span><span class="o">=</span><span class="n">val_min</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;standard&#39;</span><span class="p">:</span>
                <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">sort_by</span><span class="o">=</span><span class="n">val_min</span><span class="p">)</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Updated contemp. adjacencies:&quot;</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents</span><span class="p">(</span><span class="n">all_parents</span><span class="o">=</span><span class="n">adjt</span><span class="p">,</span> <span class="n">val_min</span><span class="o">=</span><span class="n">val_min</span><span class="p">,</span>
                                    <span class="n">pval_max</span><span class="o">=</span><span class="n">pval_max</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_any_tests_remaining</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">adjt</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">,</span>
                                              <span class="n">p</span><span class="p">)</span> <span class="ow">and</span> <span class="n">p</span> <span class="o">&lt;=</span> <span class="n">max_conds_dim</span><span class="p">):</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Algorithm converged at p = </span><span class="si">%d</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">p</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span>
                    <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Algorithm not yet converged, but max_conds_dim = </span><span class="si">%d</span><span class="s2">&quot;</span>
                    <span class="s2">&quot; reached.&quot;</span> <span class="o">%</span> <span class="n">max_conds_dim</span><span class="p">)</span>

        <span class="k">return</span> <span class="p">{</span><span class="s1">&#39;graph&#39;</span><span class="p">:</span> <span class="n">graph</span><span class="p">,</span>
                <span class="s1">&#39;sepsets&#39;</span><span class="p">:</span> <span class="n">sepsets</span><span class="p">,</span>
                <span class="s1">&#39;p_matrix&#39;</span><span class="p">:</span> <span class="n">p_matrix</span><span class="p">,</span>
                <span class="s1">&#39;val_matrix&#39;</span><span class="p">:</span> <span class="n">val_matrix</span><span class="p">,</span>
                <span class="p">}</span>

    <span class="k">def</span> <span class="nf">_get_sepsets</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns initial sepsets.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        tau_min : int, optional (default: 0)</span>
<span class="sd">            Minimum time lag to test.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        sepsets : dict</span>
<span class="sd">            Initialized sepsets.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">sepsets</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">),</span> <span class="p">[])</span>
                       <span class="k">for</span> <span class="n">tau</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">tau_min</span><span class="p">,</span> <span class="n">tau_max</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
                       <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)</span>
                       <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)])</span>

        <span class="k">return</span> <span class="n">sepsets</span>

    <span class="k">def</span> <span class="nf">_find_unshielded_triples</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Find unshielded triples i_tau o-(&gt;) k_t o-o j_t with i_tau -/- j_t.</span>

<span class="sd">        Excludes conflicting links.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        triples : list</span>
<span class="sd">            List of triples.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">N</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">include_conflicts</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>

        <span class="c1"># Find unshielded triples</span>
        <span class="c1"># Find triples i_tau o-(&gt;) k_t o-o j_t with i_tau -/- j_t</span>
        <span class="n">triples</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">tauk</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="k">if</span> <span class="n">tauk</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;o-o&quot;</span><span class="p">:</span>
                    <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">k</span><span class="p">]:</span>
                        <span class="k">if</span> <span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">)</span> <span class="o">!=</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> 
                            <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="nb">abs</span><span class="p">(</span><span class="n">taui</span><span class="p">)]</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span>
                            <span class="ow">and</span> <span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="nb">abs</span><span class="p">(</span><span class="n">taui</span><span class="p">)]</span> <span class="o">==</span> <span class="s2">&quot;o-o&quot;</span> 
                                <span class="ow">or</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="nb">abs</span><span class="p">(</span><span class="n">taui</span><span class="p">)]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span><span class="p">)):</span>
                        <span class="c1"># if not (k == j or (</span>
                        <span class="c1">#         taui == 0 and (i == k or i == j))):</span>
                        <span class="c1">#     if ((taui == 0 and graph[i, j, 0] == &quot;&quot; and</span>
                        <span class="c1">#          graph[j, i, 0] == &quot;&quot; and graph[j, k, 0] == &quot;o-o&quot;)</span>
                        <span class="c1">#             or (taui &lt; 0 and graph[j, k, 0] == &quot;o-o&quot;</span>
                        <span class="c1">#                 and graph[i, j, abs(taui)] == &quot;&quot;)):</span>
                                <span class="n">triples</span><span class="o">.</span><span class="n">append</span><span class="p">(((</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">))</span>

        <span class="k">return</span> <span class="n">triples</span>

    <span class="k">def</span> <span class="nf">_pcalg_colliders</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                        <span class="n">graph</span><span class="p">,</span>
                        <span class="n">sepsets</span><span class="p">,</span>
                        <span class="n">lagged_parents</span><span class="p">,</span>
                        <span class="n">mode</span><span class="p">,</span>
                        <span class="n">pc_alpha</span><span class="p">,</span>
                        <span class="n">tau_max</span><span class="p">,</span>
                        <span class="n">max_conds_py</span><span class="p">,</span>
                        <span class="n">max_conds_px</span><span class="p">,</span>
                        <span class="n">max_conds_px_lagged</span><span class="p">,</span>
                        <span class="n">contemp_collider_rule</span><span class="p">,</span>
                        <span class="n">conflict_resolution</span><span class="p">,</span>
                        <span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Implements the collider orientation step of the PC algorithm for</span>
<span class="sd">        time series.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape (N, N, tau_max+1)</span>
<span class="sd">            Current graph.</span>
<span class="sd">        sepsets : dictionary</span>
<span class="sd">            Separating sets. See paper for details.</span>
<span class="sd">        lagged_parents : dictionary</span>
<span class="sd">            Dictionary of form {0:[(0, -1), (3, -2), ...], 1:[], ...} containing</span>
<span class="sd">            additional conditions for each CI test. As part of PCMCIplus</span>
<span class="sd">            these are the superset of lagged parents estimated with the PC1</span>
<span class="sd">            algorithm.</span>
<span class="sd">        mode : {&#39;standard&#39;, &#39;contemp_conds&#39;}</span>
<span class="sd">            For ``mode=&#39;contemp_conds&#39;`` this implements Steps 2-4 of the</span>
<span class="sd">            PCMCIplus method. For ``mode=&#39;standard&#39;`` this implements the</span>
<span class="sd">            standard PC algorithm adapted to time series.</span>
<span class="sd">        pc_alpha : float, optional (default: 0.01)</span>
<span class="sd">            Significance level.</span>
<span class="sd">        tau_max : int, optional (default: 1)</span>
<span class="sd">            Maximum time lag. Must be larger or equal to tau_min.</span>
<span class="sd">        max_conds_py : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of Y to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X to use in MCI tests. If</span>
<span class="sd">            None is passed, this number is unrestricted.</span>
<span class="sd">        max_conds_px_lagged : int, optional (default: None)</span>
<span class="sd">            Maximum number of lagged conditions of X when X is lagged in MCI </span>
<span class="sd">            tests. If None is passed, this number is equal to max_conds_px.</span>
<span class="sd">        contemp_collider_rule : {&#39;majority&#39;, &#39;conservative&#39;, &#39;none&#39;}</span>
<span class="sd">            Rule for collider phase to use. See the paper for details. Only</span>
<span class="sd">            &#39;majority&#39; and &#39;conservative&#39; lead to an order-independent</span>
<span class="sd">            algorithm.</span>
<span class="sd">        conflict_resolution : bool, optional (default: True)</span>
<span class="sd">            Whether to mark conflicts in orientation rules. Only for True</span>
<span class="sd">            this leads to an order-independent algorithm.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Resulting causal graph, see description above for interpretation.</span>
<span class="sd">        sepsets : dictionary</span>
<span class="sd">            Separating sets. See paper for details.</span>
<span class="sd">        ambiguous_triples : list</span>
<span class="sd">            List of ambiguous triples, only relevant for &#39;majority&#39; and</span>
<span class="sd">            &#39;conservative&#39; rules, see paper for details.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">----------------------------&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Collider orientation phase&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;----------------------------&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">contemp_collider_rule = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">contemp_collider_rule</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;conflict_resolution = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">conflict_resolution</span><span class="p">)</span>

        <span class="c1"># Check that no middle mark &#39;?&#39; exists</span>
        <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">graph</span><span class="o">!=</span><span class="s1">&#39;&#39;</span><span class="p">)):</span>
            <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="n">tau</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;-&#39;</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Middle mark &#39;?&#39; exists!&quot;</span><span class="p">)</span>

        <span class="c1"># Find unshielded triples</span>
        <span class="n">triples</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_find_unshielded_triples</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>

        <span class="n">v_structures</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="n">ambiguous_triples</span> <span class="o">=</span> <span class="p">[]</span>

        <span class="k">if</span> <span class="n">contemp_collider_rule</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">contemp_collider_rule</span> <span class="o">==</span> <span class="s1">&#39;none&#39;</span><span class="p">:</span>
            <span class="c1"># Standard collider orientation rule of PC algorithm</span>
            <span class="c1"># If k_t not in sepsets(i_tau, j_t), then orient</span>
            <span class="c1"># as i_tau --&gt; k_t &lt;-- j_t</span>
            <span class="k">for</span> <span class="n">itaukj</span> <span class="ow">in</span> <span class="n">triples</span><span class="p">:</span>
                <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">itaukj</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]:</span>
                    <span class="n">v_structures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Apply &#39;majority&#39; or &#39;conservative&#39; rule to orient colliders          </span>
            <span class="c1"># Compute all (contemp) subsets of potential parents of i and all </span>
            <span class="c1"># subsets of potential parents of j that make i and j independent</span>
            <span class="k">def</span> <span class="nf">subsets</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> <span class="k">return</span> <span class="p">[]</span>
                <span class="n">subsets</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="k">for</span> <span class="n">cardinality</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
                    <span class="n">subsets</span> <span class="o">+=</span> <span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">cardinality</span><span class="p">))</span>
                <span class="n">subsets</span> <span class="o">=</span> <span class="p">[</span><span class="nb">list</span><span class="p">(</span><span class="n">sub</span><span class="p">)</span> <span class="k">for</span> <span class="n">sub</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">subsets</span><span class="p">))]</span>
                <span class="k">return</span> <span class="n">subsets</span>

            <span class="c1"># We only consider contemporaneous adjacencies because only these</span>
            <span class="c1"># can include the (contemp) k. Furthermore, next to adjacencies of j,</span>
            <span class="c1"># we only need to check adjacencies of i for tau=0</span>
            <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;contemp_conds&#39;</span><span class="p">:</span>
                <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series_contemp</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">mode</span> <span class="o">==</span> <span class="s1">&#39;standard&#39;</span><span class="p">:</span>
                <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>

            <span class="n">n_triples</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">triples</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">ir</span><span class="p">,</span> <span class="n">itaukj</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">triples</span><span class="p">):</span>
                <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">itaukj</span>

                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_print_triple_info</span><span class="p">(</span><span class="n">itaukj</span><span class="p">,</span> <span class="n">ir</span><span class="p">,</span> <span class="n">n_triples</span><span class="p">)</span>

                <span class="n">neighbor_subsets_tmp</span> <span class="o">=</span> <span class="n">subsets</span><span class="p">(</span>
                    <span class="p">[(</span><span class="n">l</span><span class="p">,</span> <span class="n">taul</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">taul</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>
                     <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">l</span> <span class="o">==</span> <span class="n">i</span> <span class="ow">and</span> <span class="n">tau</span> <span class="o">==</span> <span class="n">taul</span><span class="p">)])</span>
                <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                    <span class="c1"># Furthermore, we only need to check contemp. adjacencies</span>
                    <span class="c1"># of i for tau=0</span>
                    <span class="n">neighbor_subsets_tmp</span> <span class="o">+=</span> <span class="n">subsets</span><span class="p">(</span>
                        <span class="p">[(</span><span class="n">l</span><span class="p">,</span> <span class="n">taul</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">taul</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
                         <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">l</span> <span class="o">==</span> <span class="n">j</span> <span class="ow">and</span> <span class="n">taul</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)])</span>

                <span class="c1"># Make unique</span>
                <span class="n">neighbor_subsets</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="k">for</span> <span class="n">subset</span> <span class="ow">in</span> <span class="n">neighbor_subsets_tmp</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">subset</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">neighbor_subsets</span><span class="p">:</span>
                        <span class="n">neighbor_subsets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">subset</span><span class="p">)</span>

                <span class="n">n_neighbors</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">neighbor_subsets</span><span class="p">)</span>

                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span>
                        <span class="s2">&quot;    Iterate through </span><span class="si">%d</span><span class="s2"> condition subset(s) of &quot;</span>
                        <span class="s2">&quot;neighbors: &quot;</span> <span class="o">%</span> <span class="n">n_neighbors</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">lagged_parents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">_print_pcmciplus_conditions</span><span class="p">(</span><span class="n">lagged_parents</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span>
                                         <span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">),</span> <span class="n">max_conds_py</span><span class="p">,</span> <span class="n">max_conds_px</span><span class="p">,</span>
                                         <span class="n">max_conds_px_lagged</span><span class="p">)</span>

                <span class="c1"># Test which neighbor subsets separate i and j</span>
                <span class="n">neighbor_sepsets</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="k">for</span> <span class="n">iss</span><span class="p">,</span> <span class="n">S</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">neighbor_subsets</span><span class="p">):</span>
                    <span class="n">val</span><span class="p">,</span> <span class="n">pval</span><span class="p">,</span> <span class="n">Z</span><span class="p">,</span> <span class="n">dependent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_run_pcalg_test</span><span class="p">(</span><span class="n">graph</span><span class="o">=</span><span class="n">graph</span><span class="p">,</span>
                            <span class="n">i</span><span class="o">=</span><span class="n">i</span><span class="p">,</span> <span class="n">abstau</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="o">=</span><span class="n">j</span><span class="p">,</span> <span class="n">S</span><span class="o">=</span><span class="n">S</span><span class="p">,</span> <span class="n">lagged_parents</span><span class="o">=</span><span class="n">lagged_parents</span><span class="p">,</span> 
                            <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
                            <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span> <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
                            <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> <span class="n">alpha_or_thres</span><span class="o">=</span><span class="n">pc_alpha</span><span class="p">)</span>

                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">_print_cond_info</span><span class="p">(</span><span class="n">Z</span><span class="o">=</span><span class="n">S</span><span class="p">,</span> <span class="n">comb_index</span><span class="o">=</span><span class="n">iss</span><span class="p">,</span> <span class="n">pval</span><span class="o">=</span><span class="n">pval</span><span class="p">,</span>
                                              <span class="n">val</span><span class="o">=</span><span class="n">val</span><span class="p">)</span>

                    <span class="k">if</span> <span class="ow">not</span> <span class="n">dependent</span><span class="p">:</span> <span class="c1">#pval &gt; pc_alpha:</span>
                        <span class="n">neighbor_sepsets</span> <span class="o">+=</span> <span class="p">[</span><span class="n">S</span><span class="p">]</span>

                <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">neighbor_sepsets</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                    <span class="n">fraction</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span>
                        <span class="p">[(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">S</span> <span class="k">for</span> <span class="n">S</span> <span class="ow">in</span> <span class="n">neighbor_sepsets</span><span class="p">])</span> <span class="o">/</span> <span class="nb">float</span><span class="p">(</span>
                        <span class="nb">len</span><span class="p">(</span><span class="n">neighbor_sepsets</span><span class="p">))</span>

                <span class="k">if</span> <span class="n">contemp_collider_rule</span> <span class="o">==</span> <span class="s1">&#39;conservative&#39;</span><span class="p">:</span>
                    <span class="c1"># Triple is labeled as unambiguous if at least one</span>
                    <span class="c1"># separating set is found and either k is in ALL</span>
                    <span class="c1"># (fraction == 1) or NONE (fraction == 0) of them</span>
                    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">neighbor_sepsets</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span>
                                <span class="s2">&quot;    No separating subsets --&gt; ambiguous &quot;</span>
                                <span class="s2">&quot;triple found&quot;</span><span class="p">)</span>
                        <span class="n">ambiguous_triples</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="k">if</span> <span class="n">fraction</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="c1"># If (k, 0) is in none of the neighbor_sepsets,</span>
                            <span class="c1"># orient as collider</span>
                            <span class="n">v_structures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;    Fraction of separating subsets &quot;</span>
                                    <span class="s2">&quot;containing (</span><span class="si">%s</span><span class="s2"> 0) is = 0 --&gt; collider &quot;</span>
                                    <span class="s2">&quot;found&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                            <span class="c1"># Also delete (k, 0) from sepsets (if present)</span>
                            <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]:</span>
                                <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]</span><span class="o">.</span><span class="n">remove</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]:</span>
                                    <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]</span><span class="o">.</span><span class="n">remove</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                        <span class="k">elif</span> <span class="n">fraction</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="c1"># If (k, 0) is in all of the neighbor_sepsets,</span>
                            <span class="c1"># leave unoriented</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;    Fraction of separating subsets &quot;</span>
                                    <span class="s2">&quot;containing (</span><span class="si">%s</span><span class="s2"> 0) is = 1 --&gt; &quot;</span>
                                    <span class="s2">&quot;non-collider found&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                            <span class="c1"># Also add (k, 0) to sepsets (if not present)</span>
                            <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]:</span>
                                <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]:</span>
                                    <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                        <span class="k">else</span><span class="p">:</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;    Fraction of separating subsets &quot;</span>
                                    <span class="s2">&quot;containing (</span><span class="si">%s</span><span class="s2"> 0) is = between 0 and 1 &quot;</span>
                                    <span class="s2">&quot;--&gt; ambiguous triple found&quot;</span> <span class="o">%</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                            <span class="n">ambiguous_triples</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>

                <span class="k">elif</span> <span class="n">contemp_collider_rule</span> <span class="o">==</span> <span class="s1">&#39;majority&#39;</span><span class="p">:</span>

                    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">neighbor_sepsets</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span>
                                <span class="s2">&quot;    No separating subsets --&gt; ambiguous &quot;</span>
                                <span class="s2">&quot;triple found&quot;</span><span class="p">)</span>
                        <span class="n">ambiguous_triples</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>
                    <span class="k">else</span><span class="p">:</span>
                        <span class="k">if</span> <span class="n">fraction</span> <span class="o">==</span> <span class="mf">0.5</span><span class="p">:</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;    Fraction of separating subsets &quot;</span>
                                    <span class="s2">&quot;containing (</span><span class="si">%s</span><span class="s2"> 0) is = 0.5 --&gt; ambiguous &quot;</span>
                                    <span class="s2">&quot;triple found&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                            <span class="n">ambiguous_triples</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>
                        <span class="k">elif</span> <span class="n">fraction</span> <span class="o">&lt;</span> <span class="mf">0.5</span><span class="p">:</span>
                            <span class="n">v_structures</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">itaukj</span><span class="p">)</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;    Fraction of separating subsets &quot;</span>
                                    <span class="s2">&quot;containing (</span><span class="si">%s</span><span class="s2"> 0) is &lt; 0.5 &quot;</span>
                                    <span class="s2">&quot;--&gt; collider found&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                            <span class="c1"># Also delete (k, 0) from sepsets (if present)</span>
                            <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]:</span>
                                <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]</span><span class="o">.</span><span class="n">remove</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]:</span>
                                    <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]</span><span class="o">.</span><span class="n">remove</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                        <span class="k">elif</span> <span class="n">fraction</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">:</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;    Fraction of separating subsets &quot;</span>
                                    <span class="s2">&quot;containing (</span><span class="si">%s</span><span class="s2"> 0) is &gt; 0.5 &quot;</span>
                                    <span class="s2">&quot;--&gt; non-collider found&quot;</span> <span class="o">%</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
                            <span class="c1"># Also add (k, 0) to sepsets (if not present)</span>
                            <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]:</span>
                                <span class="n">sepsets</span><span class="p">[((</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">j</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
                            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                                <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]:</span>
                                    <span class="n">sepsets</span><span class="p">[((</span><span class="n">j</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">i</span><span class="p">)]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">v_structures</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Orienting links among colliders:&quot;</span><span class="p">)</span>

        <span class="n">link_marker</span> <span class="o">=</span> <span class="p">{</span><span class="kc">True</span><span class="p">:</span><span class="s2">&quot;o-o&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">:</span><span class="s2">&quot;--&gt;&quot;</span><span class="p">}</span>

        <span class="c1"># Now go through list of v-structures and (optionally) detect conflicts</span>
        <span class="n">oriented_links</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">itaukj</span> <span class="ow">in</span> <span class="n">v_structures</span><span class="p">:</span>
            <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">itaukj</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">    Collider (</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2">:&quot;</span> <span class="o">%</span> <span class="p">(</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">tau</span><span class="p">,</span> <span class="n">link_marker</span><span class="p">[</span>
                        <span class="n">tau</span><span class="o">==</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>

            <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span> <span class="ow">and</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;      Orient </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2"> as </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2"> &quot;</span> <span class="o">%</span> <span class="p">(</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">]))</span>
                <span class="c1"># graph[k, j, 0] = 0</span>
                <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;--&quot;</span> <span class="c1">#0</span>
                <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;--&gt;&quot;</span>

                <span class="n">oriented_links</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">))</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">conflict_resolution</span> <span class="ow">is</span> <span class="kc">False</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;      Already oriented&quot;</span><span class="p">)</span>

            <span class="k">if</span> <span class="n">conflict_resolution</span><span class="p">:</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="nb">print</span><span class="p">(</span>
                            <span class="s2">&quot;        Conflict since </span><span class="si">%s</span><span class="s2"> &lt;-- </span><span class="si">%s</span><span class="s2"> already &quot;</span>
                            <span class="s2">&quot;oriented: Mark link as `2` in graph&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">]))</span>
                    <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;x-x&quot;</span> <span class="c1">#2</span>

            <span class="k">if</span> <span class="n">tau</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span> <span class="ow">and</span> <span class="p">(</span>
                        <span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;      Orient </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2"> as </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2"> &quot;</span> <span class="o">%</span> <span class="p">(</span>
                            <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
                            <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">]))</span>
                    <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&lt;--&quot;</span> <span class="c1">#0</span>
                    <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;--&gt;&quot;</span>

                    <span class="n">oriented_links</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">k</span><span class="p">))</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">conflict_resolution</span> <span class="ow">is</span> <span class="kc">False</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;      Already oriented&quot;</span><span class="p">)</span>

                <span class="k">if</span> <span class="n">conflict_resolution</span><span class="p">:</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span>
                                <span class="s2">&quot;        Conflict since </span><span class="si">%s</span><span class="s2"> &lt;-- </span><span class="si">%s</span><span class="s2"> already &quot;</span>
                                <span class="s2">&quot;oriented: Mark link as `2` in graph&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">]))</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;x-x&quot;</span>  <span class="c1">#2</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Updated adjacencies:&quot;</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents</span><span class="p">(</span><span class="n">all_parents</span><span class="o">=</span><span class="n">adjt</span><span class="p">,</span> <span class="n">val_min</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pval_max</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>

        <span class="k">return</span> <span class="p">{</span><span class="s1">&#39;graph&#39;</span><span class="p">:</span> <span class="n">graph</span><span class="p">,</span>
                <span class="s1">&#39;sepsets&#39;</span><span class="p">:</span> <span class="n">sepsets</span><span class="p">,</span>
                <span class="s1">&#39;ambiguous_triples&#39;</span><span class="p">:</span> <span class="n">ambiguous_triples</span><span class="p">,</span>
                <span class="p">}</span>

    <span class="k">def</span> <span class="nf">_find_triples_rule1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Find triples i_tau --&gt; k_t o-o j_t with i_tau -/- j_t.</span>

<span class="sd">        Excludes conflicting links.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        triples : list</span>
<span class="sd">            List of triples.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">include_conflicts</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>

        <span class="n">N</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">triples</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">tauk</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="k">if</span> <span class="n">tauk</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;o-o&#39;</span><span class="p">:</span>
                    <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjt</span><span class="p">[</span><span class="n">k</span><span class="p">]:</span>
                        <span class="k">if</span> <span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">)</span> <span class="o">!=</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> 
                            <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="nb">abs</span><span class="p">(</span><span class="n">taui</span><span class="p">)]</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span>
                            <span class="ow">and</span> <span class="p">(</span><span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span><span class="n">k</span><span class="p">,</span><span class="nb">abs</span><span class="p">(</span><span class="n">taui</span><span class="p">)]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span><span class="p">)):</span>
                                <span class="n">triples</span><span class="o">.</span><span class="n">append</span><span class="p">(((</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">triples</span>

    <span class="k">def</span> <span class="nf">_find_triples_rule2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Find triples i_t --&gt; k_t --&gt; j_t with i_t o-o j_t.</span>

<span class="sd">        Excludes conflicting links.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        triples : list</span>
<span class="sd">            List of triples.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">adjtcont</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series_contemp</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span>
                                                     <span class="n">include_conflicts</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
        <span class="n">N</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

        <span class="n">triples</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">tauk</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjtcont</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;--&gt;&#39;</span><span class="p">:</span>
                    <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjtcont</span><span class="p">[</span><span class="n">k</span><span class="p">]:</span>
                        <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;--&gt;&#39;</span> <span class="ow">and</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">taui</span><span class="p">)</span> <span class="o">!=</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span>
                            <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;o-o&#39;</span> <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;o-o&#39;</span><span class="p">:</span>
                                <span class="n">triples</span><span class="o">.</span><span class="n">append</span><span class="p">(((</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">triples</span>

    <span class="k">def</span> <span class="nf">_find_chains_rule3</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">graph</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Find chains i_t o-o k_t --&gt; j_t and i_t o-o l_t --&gt; j_t with</span>
<span class="sd">           i_t o-o j_t and k_t -/- l_t.</span>

<span class="sd">        Excludes conflicting links.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Causal graph, see description above for interpretation.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        chains : list</span>
<span class="sd">            List of chains.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">N</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">adjtcont</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series_contemp</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span>
                                                     <span class="n">include_conflicts</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>

        <span class="n">chains</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
            <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjtcont</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                <span class="k">if</span> <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;o-o&#39;</span><span class="p">:</span>
                    <span class="k">for</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjtcont</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                        <span class="k">for</span> <span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="n">adjtcont</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
                            <span class="k">if</span> <span class="p">((</span><span class="n">k</span> <span class="o">!=</span> <span class="n">l</span><span class="p">)</span> 
                                <span class="ow">and</span> <span class="p">(</span><span class="n">k</span> <span class="o">!=</span> <span class="n">i</span><span class="p">)</span> 
                                <span class="ow">and</span> <span class="p">(</span><span class="n">l</span> <span class="o">!=</span> <span class="n">i</span><span class="p">)</span>
                                <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span>
                                <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">l</span><span class="p">,</span><span class="n">j</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span>
                                <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;o-o&quot;</span>
                                <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">l</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;o-o&quot;</span>
                                <span class="ow">and</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span><span class="n">l</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span>
                                <span class="p">):</span>
                                <span class="n">chains</span><span class="o">.</span><span class="n">append</span><span class="p">((((</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">),</span>
                                               <span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">l</span><span class="p">,</span> <span class="n">j</span><span class="p">)))</span>

        <span class="k">return</span> <span class="n">chains</span>

    <span class="k">def</span> <span class="nf">_pcalg_rules_timeseries</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                                <span class="n">graph</span><span class="p">,</span>
                                <span class="n">ambiguous_triples</span><span class="p">,</span>
                                <span class="n">conflict_resolution</span><span class="p">,</span>
                                <span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Implements the rule orientation step of the PC algorithm for</span>
<span class="sd">        time series.</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        graph : array of shape (N, N, tau_max+1)</span>
<span class="sd">            Current graph.</span>
<span class="sd">        ambiguous_triples : list</span>
<span class="sd">            List of ambiguous triples, only relevant for &#39;majority&#39; and</span>
<span class="sd">            &#39;conservative&#39; rules, see paper for details.</span>
<span class="sd">        conflict_resolution : bool</span>
<span class="sd">            Whether to mark conflicts in orientation rules. Only for True</span>
<span class="sd">            this leads to an order-independent algorithm.</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        graph : array of shape [N, N, tau_max+1]</span>
<span class="sd">            Resulting causal graph, see description above for interpretation.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">N</span> <span class="o">=</span> <span class="n">graph</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

        <span class="k">def</span> <span class="nf">rule1</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">oriented_links</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Find (unambiguous) triples i_tau --&gt; k_t o-o j_t with</span>
<span class="sd">               i_tau -/- j_t and orient as i_tau --&gt; k_t --&gt; j_t.</span>
<span class="sd">            &quot;&quot;&quot;</span>
            <span class="n">triples</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_find_triples_rule1</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
            <span class="n">triples_left</span> <span class="o">=</span> <span class="kc">False</span>

            <span class="k">for</span> <span class="n">itaukj</span> <span class="ow">in</span> <span class="n">triples</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">itaukj</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ambiguous_triples</span><span class="p">:</span>
                    <span class="n">triples_left</span> <span class="o">=</span> <span class="kc">True</span>
                    <span class="c1"># Orient as i_tau --&gt; k_t --&gt; j_t</span>
                    <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">itaukj</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span> <span class="ow">and</span> <span class="p">(</span>
                            <span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span>
                                <span class="s2">&quot;    R1: Found (</span><span class="si">%s</span><span class="s2"> </span><span class="si">% d</span><span class="s2">) --&gt; </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2">, &quot;</span>
                                <span class="s2">&quot;orient as </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">tau</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
                        <span class="c1"># graph[j, k, 0] = 0</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;--&gt;&#39;</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&lt;--&#39;</span>  <span class="c1"># 0</span>

                        <span class="n">oriented_links</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">))</span>

                    <span class="k">if</span> <span class="n">conflict_resolution</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;        Conflict since </span><span class="si">%s</span><span class="s2"> &lt;-- </span><span class="si">%s</span><span class="s2"> already&quot;</span>
                                    <span class="s2">&quot; oriented: Mark link as `2` in graph&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
                            <span class="c1"># graph[j, k, 0] = graph[k, j, 0] = 2</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">k</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;x-x&#39;</span>

            <span class="k">return</span> <span class="n">triples_left</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">oriented_links</span>

        <span class="k">def</span> <span class="nf">rule2</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">oriented_links</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Find (unambiguous) triples i_t --&gt; k_t --&gt; j_t with i_t o-o j_t</span>
<span class="sd">               and orient as i_t --&gt; j_t.</span>
<span class="sd">            &quot;&quot;&quot;</span>

            <span class="n">triples</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_find_triples_rule2</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
            <span class="n">triples_left</span> <span class="o">=</span> <span class="kc">False</span>

            <span class="k">for</span> <span class="n">itaukj</span> <span class="ow">in</span> <span class="n">triples</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">itaukj</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ambiguous_triples</span><span class="p">:</span>
                    <span class="c1"># TODO: CHeck whether this is actually needed</span>
                    <span class="c1"># since ambiguous triples are always unshielded and here</span>
                    <span class="c1"># we look for triples where i and j are connected</span>
                    <span class="n">triples_left</span> <span class="o">=</span> <span class="kc">True</span>
                    <span class="c1"># Orient as i_t --&gt; j_t</span>
                    <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">itaukj</span>
                    <span class="k">if</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span> <span class="ow">and</span> <span class="p">(</span>
                            <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span>
                                <span class="s2">&quot;    R2: Found </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">  with  </span><span class="si">%s</span><span class="s2"> &quot;</span>
                                <span class="s2">&quot;o-o </span><span class="si">%s</span><span class="s2">, orient as </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;--&gt;&#39;</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&lt;--&#39;</span>  <span class="c1"># 0</span>

                        <span class="n">oriented_links</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">))</span>
                    <span class="k">if</span> <span class="n">conflict_resolution</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;        Conflict since </span><span class="si">%s</span><span class="s2"> &lt;-- </span><span class="si">%s</span><span class="s2"> already &quot;</span>
                                    <span class="s2">&quot;oriented: Mark link as `2` in graph&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
                            <span class="c1"># graph[j, i, 0] = graph[i, j, 0] = 2</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;x-x&#39;</span>

            <span class="k">return</span> <span class="n">triples_left</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">oriented_links</span>

        <span class="k">def</span> <span class="nf">rule3</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">oriented_links</span><span class="p">):</span>
<span class="w">            </span><span class="sd">&quot;&quot;&quot;Find (unambiguous) chains i_t o-o k_t --&gt; j_t</span>
<span class="sd">               and i_t o-o l_t --&gt; j_t with i_t o-o j_t</span>
<span class="sd">               and k_t -/- l_t: Orient as i_t --&gt; j_t.</span>
<span class="sd">            &quot;&quot;&quot;</span>
            <span class="c1"># First find all chains i_t -- k_t --&gt; j_t with i_t -- j_t</span>
            <span class="c1"># and k_t -/- l_t</span>
            <span class="n">chains</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_find_chains_rule3</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>

            <span class="n">chains_left</span> <span class="o">=</span> <span class="kc">False</span>

            <span class="k">for</span> <span class="p">(</span><span class="n">itaukj</span><span class="p">,</span> <span class="n">itaulj</span><span class="p">)</span> <span class="ow">in</span> <span class="n">chains</span><span class="p">:</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">itaukj</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ambiguous_triples</span> <span class="ow">and</span>
                        <span class="n">itaulj</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ambiguous_triples</span><span class="p">):</span>
                    <span class="c1"># TODO: CHeck whether this is actually needed</span>
                    <span class="c1"># since ambiguous triples are always unshielded and here</span>
                    <span class="c1"># we look for triples where i and j are connected</span>
                    <span class="n">chains_left</span> <span class="o">=</span> <span class="kc">True</span>
                    <span class="c1"># Orient as i_t --&gt; j_t</span>
                    <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tau</span><span class="p">),</span> <span class="n">k</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">itaukj</span>
                    <span class="n">_</span>       <span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">itaulj</span>

                    <span class="k">if</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span> <span class="ow">and</span> <span class="p">(</span>
                            <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                            <span class="nb">print</span><span class="p">(</span>
                                <span class="s2">&quot;    R3: Found </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2"> and </span><span class="si">%s</span><span class="s2"> o-o &quot;</span>
                                <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2"> with </span><span class="si">%s</span><span class="s2"> o-o </span><span class="si">%s</span><span class="s2"> and </span><span class="si">%s</span><span class="s2"> -/- </span><span class="si">%s</span><span class="s2">, &quot;</span>
                                <span class="s2">&quot;orient as </span><span class="si">%s</span><span class="s2"> --&gt; </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">l</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">k</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">l</span><span class="p">],</span>
                                    <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;--&gt;&#39;</span>
                        <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;&lt;--&#39;</span>  <span class="c1"># 0</span>

                        <span class="n">oriented_links</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">))</span>
                    <span class="k">if</span> <span class="n">conflict_resolution</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="ow">in</span> <span class="n">oriented_links</span><span class="p">:</span>
                            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                                <span class="nb">print</span><span class="p">(</span>
                                    <span class="s2">&quot;        Conflict since </span><span class="si">%s</span><span class="s2"> &lt;-- </span><span class="si">%s</span><span class="s2"> already &quot;</span>
                                    <span class="s2">&quot;oriented: Mark link as `2` in graph&quot;</span> <span class="o">%</span> <span class="p">(</span>
                                        <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">var_names</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
                            <span class="n">graph</span><span class="p">[</span><span class="n">j</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">graph</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;x-x&#39;</span>

            <span class="k">return</span> <span class="n">chains_left</span><span class="p">,</span> <span class="n">graph</span><span class="p">,</span> <span class="n">oriented_links</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;----------------------------&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Rule orientation phase&quot;</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;----------------------------&quot;</span><span class="p">)</span>

        <span class="n">oriented_links</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="n">graph_new</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">graph</span><span class="p">)</span>
        <span class="n">any1</span> <span class="o">=</span> <span class="n">any2</span> <span class="o">=</span> <span class="n">any3</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">any1</span> <span class="ow">or</span> <span class="n">any2</span> <span class="ow">or</span> <span class="n">any3</span><span class="p">):</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Try rule(s) </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                    <span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="n">any1</span><span class="p">,</span> <span class="n">any2</span><span class="p">,</span> <span class="n">any3</span><span class="p">]))))</span>
            <span class="n">any1</span><span class="p">,</span> <span class="n">graph_new</span><span class="p">,</span> <span class="n">oriented_links</span> <span class="o">=</span> <span class="n">rule1</span><span class="p">(</span><span class="n">graph_new</span><span class="p">,</span> <span class="n">oriented_links</span><span class="p">)</span>
            <span class="n">any2</span><span class="p">,</span> <span class="n">graph_new</span><span class="p">,</span> <span class="n">oriented_links</span> <span class="o">=</span> <span class="n">rule2</span><span class="p">(</span><span class="n">graph_new</span><span class="p">,</span> <span class="n">oriented_links</span><span class="p">)</span>
            <span class="n">any3</span><span class="p">,</span> <span class="n">graph_new</span><span class="p">,</span> <span class="n">oriented_links</span> <span class="o">=</span> <span class="n">rule3</span><span class="p">(</span><span class="n">graph_new</span><span class="p">,</span> <span class="n">oriented_links</span><span class="p">)</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">adjt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_adj_time_series</span><span class="p">(</span><span class="n">graph_new</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Updated adjacencies:&quot;</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_print_parents</span><span class="p">(</span><span class="n">all_parents</span><span class="o">=</span><span class="n">adjt</span><span class="p">,</span> <span class="n">val_min</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pval_max</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">graph_new</span>

    <span class="k">def</span> <span class="nf">_optimize_pcmciplus_alpha</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
                      <span class="n">link_assumptions</span><span class="p">,</span>
                      <span class="n">tau_min</span><span class="p">,</span>
                      <span class="n">tau_max</span><span class="p">,</span>
                      <span class="n">pc_alpha</span><span class="p">,</span>
                      <span class="n">contemp_collider_rule</span><span class="p">,</span>
                      <span class="n">conflict_resolution</span><span class="p">,</span>
                      <span class="n">reset_lagged_links</span><span class="p">,</span>
                      <span class="n">max_conds_dim</span><span class="p">,</span>
                      <span class="n">max_combinations</span><span class="p">,</span>
                      <span class="n">max_conds_py</span><span class="p">,</span>
                      <span class="n">max_conds_px</span><span class="p">,</span>
                      <span class="n">max_conds_px_lagged</span><span class="p">,</span>
                      <span class="n">fdr_method</span><span class="p">,</span>
                      <span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Optimizes pc_alpha in PCMCIplus.</span>

<span class="sd">        If a list or None is passed for ``pc_alpha``, the significance level is</span>
<span class="sd">        optimized for every graph across the given ``pc_alpha`` values using the</span>
<span class="sd">        score computed in ``cond_ind_test.get_model_selection_criterion()``</span>

<span class="sd">        Parameters</span>
<span class="sd">        ----------</span>
<span class="sd">        See those for run_pcmciplus()</span>

<span class="sd">        Returns</span>
<span class="sd">        -------</span>
<span class="sd">        Results for run_pcmciplus() for the optimal pc_alpha.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="n">pc_alpha</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">pc_alpha_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">0.001</span><span class="p">,</span> <span class="mf">0.005</span><span class="p">,</span> <span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.025</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">pc_alpha_list</span> <span class="o">=</span> <span class="n">pc_alpha</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Optimizing pc_alpha over &quot;</span> <span class="o">+</span> 
                  <span class="s2">&quot;pc_alpha_list = </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">pc_alpha_list</span><span class="p">)</span> <span class="o">+</span>
                  <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##&quot;</span><span class="p">)</span>

        <span class="n">results</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="n">score</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros_like</span><span class="p">(</span><span class="n">pc_alpha_list</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">iscore</span><span class="p">,</span> <span class="n">pc_alpha_here</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">pc_alpha_list</span><span class="p">):</span>
            <span class="c1"># Print statement about the pc_alpha being tested</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">## pc_alpha = </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%d</span><span class="s2">/</span><span class="si">%d</span><span class="s2">):&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pc_alpha_here</span><span class="p">,</span>
                                                      <span class="n">iscore</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
                                                      <span class="n">score</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
            <span class="c1"># Get the results for this alpha value</span>
            <span class="n">results</span><span class="p">[</span><span class="n">pc_alpha_here</span><span class="p">]</span> <span class="o">=</span> \
                <span class="bp">self</span><span class="o">.</span><span class="n">run_pcmciplus</span><span class="p">(</span><span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span><span class="p">,</span>
                                    <span class="n">tau_min</span><span class="o">=</span><span class="n">tau_min</span><span class="p">,</span>
                                    <span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span>
                                    <span class="n">pc_alpha</span><span class="o">=</span><span class="n">pc_alpha_here</span><span class="p">,</span>
                                    <span class="n">contemp_collider_rule</span><span class="o">=</span><span class="n">contemp_collider_rule</span><span class="p">,</span>
                                    <span class="n">conflict_resolution</span><span class="o">=</span><span class="n">conflict_resolution</span><span class="p">,</span>
                                    <span class="n">reset_lagged_links</span><span class="o">=</span><span class="n">reset_lagged_links</span><span class="p">,</span>
                                    <span class="n">max_conds_dim</span><span class="o">=</span><span class="n">max_conds_dim</span><span class="p">,</span>
                                    <span class="n">max_combinations</span><span class="o">=</span><span class="n">max_combinations</span><span class="p">,</span>
                                    <span class="n">max_conds_py</span><span class="o">=</span><span class="n">max_conds_py</span><span class="p">,</span>
                                    <span class="n">max_conds_px</span><span class="o">=</span><span class="n">max_conds_px</span><span class="p">,</span>
                                    <span class="n">max_conds_px_lagged</span><span class="o">=</span><span class="n">max_conds_px_lagged</span><span class="p">,</span>
                                    <span class="n">fdr_method</span><span class="o">=</span><span class="n">fdr_method</span><span class="p">)</span>

            <span class="c1"># Get one member of the Markov equivalence class of the result</span>
            <span class="c1"># of PCMCIplus, which is a CPDAG</span>

            <span class="c1"># First create order that is based on some feature of the variables</span>
            <span class="c1"># to avoid order-dependence of DAG, i.e., it should not matter</span>
            <span class="c1"># in which order the variables appear in dataframe</span>
            <span class="c1"># Here we use the sum of absolute val_matrix values incident at j</span>
            <span class="n">val_matrix</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="n">pc_alpha_here</span><span class="p">][</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">]</span>
            <span class="n">variable_order</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argsort</span><span class="p">(</span>
                                <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">val_matrix</span><span class="p">)</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">)))[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>

            <span class="n">dag</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_dag_from_cpdag</span><span class="p">(</span>
                            <span class="n">cpdag_graph</span><span class="o">=</span><span class="n">results</span><span class="p">[</span><span class="n">pc_alpha_here</span><span class="p">][</span><span class="s1">&#39;graph&#39;</span><span class="p">],</span>
                            <span class="n">variable_order</span><span class="o">=</span><span class="n">variable_order</span><span class="p">)</span>
            

            <span class="c1"># Compute the best average score when the model selection</span>
            <span class="c1"># is applied to all N variables</span>
            <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">):</span>
                <span class="n">parents</span> <span class="o">=</span> <span class="p">[]</span>
                <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">tau</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">dag</span><span class="p">[:,</span><span class="n">j</span><span class="p">,:]</span> <span class="o">==</span> <span class="s2">&quot;--&gt;&quot;</span><span class="p">)):</span>
                    <span class="n">parents</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">tau</span><span class="p">))</span>
                <span class="n">score_j</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cond_ind_test</span><span class="o">.</span><span class="n">get_model_selection_criterion</span><span class="p">(</span>
                        <span class="n">j</span><span class="p">,</span> <span class="n">parents</span><span class="p">,</span> <span class="n">tau_max</span><span class="p">)</span>
                <span class="n">score</span><span class="p">[</span><span class="n">iscore</span><span class="p">]</span> <span class="o">+=</span> <span class="n">score_j</span>
            <span class="n">score</span><span class="p">[</span><span class="n">iscore</span><span class="p">]</span> <span class="o">/=</span> <span class="nb">float</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">N</span><span class="p">)</span>

        <span class="c1"># Record the optimal alpha value</span>
        <span class="n">optimal_alpha</span> <span class="o">=</span> <span class="n">pc_alpha_list</span><span class="p">[</span><span class="n">score</span><span class="o">.</span><span class="n">argmin</span><span class="p">()]</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbosity</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##&quot;</span><span class="o">+</span>
                  <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">## Scores for individual pc_alpha values:</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">iscore</span><span class="p">,</span> <span class="n">pc_alpha</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">pc_alpha_list</span><span class="p">):</span>
                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;   pc_alpha = </span><span class="si">%7s</span><span class="s2"> yields score = </span><span class="si">%.5f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pc_alpha</span><span class="p">,</span> 
                                                                <span class="n">score</span><span class="p">[</span><span class="n">iscore</span><span class="p">]))</span>
            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">##</span><span class="se">\n</span><span class="s2">## Results for optimal &quot;</span> <span class="o">+</span>
                  <span class="s2">&quot;pc_alpha = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">##&quot;</span> <span class="o">%</span> <span class="n">optimal_alpha</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">print_results</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="n">optimal_alpha</span><span class="p">],</span> <span class="n">alpha_level</span><span class="o">=</span><span class="n">optimal_alpha</span><span class="p">)</span>

        <span class="n">optimal_results</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="n">optimal_alpha</span><span class="p">]</span>
        <span class="n">optimal_results</span><span class="p">[</span><span class="s1">&#39;optimal_alpha&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">optimal_alpha</span>
        <span class="k">return</span> <span class="n">optimal_results</span></div>



<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">tigramite.independence_tests.parcorr</span> <span class="kn">import</span> <span class="n">ParCorr</span>
    <span class="kn">from</span> <span class="nn">tigramite.independence_tests.cmiknn</span> <span class="kn">import</span> <span class="n">CMIknn</span>

    <span class="kn">import</span> <span class="nn">tigramite.data_processing</span> <span class="k">as</span> <span class="nn">pp</span>
    <span class="kn">from</span> <span class="nn">tigramite.toymodels</span> <span class="kn">import</span> <span class="n">structural_causal_processes</span> <span class="k">as</span> <span class="n">toys</span>
    <span class="kn">import</span> <span class="nn">tigramite.plotting</span> <span class="k">as</span> <span class="nn">tp</span>
    <span class="kn">from</span> <span class="nn">matplotlib</span> <span class="kn">import</span> <span class="n">pyplot</span> <span class="k">as</span> <span class="n">plt</span>

    <span class="n">random_state</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">default_rng</span><span class="p">(</span><span class="n">seed</span><span class="o">=</span><span class="mi">43</span><span class="p">)</span>
    <span class="c1"># Example process to play around with</span>
    <span class="c1"># Each key refers to a variable and the incoming links are supplied</span>
    <span class="c1"># as a list of format [((var, -lag), coeff, function), ...]</span>
    <span class="k">def</span> <span class="nf">lin_f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="k">return</span> <span class="n">x</span>
    <span class="k">def</span> <span class="nf">nonlin_f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="k">return</span> <span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="mf">5.</span> <span class="o">*</span> <span class="n">x</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">x</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">20.</span><span class="p">))</span>

    <span class="n">T</span> <span class="o">=</span> <span class="mi">1000</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">random_state</span><span class="o">.</span><span class="n">standard_normal</span><span class="p">((</span><span class="n">T</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>
    <span class="c1"># Simple sun</span>
    <span class="n">data</span><span class="p">[:,</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="n">random_state</span><span class="o">.</span><span class="n">standard_normal</span><span class="p">((</span><span class="n">T</span><span class="p">))</span> <span class="c1"># np.sin(np.arange(T)*20/np.pi) + 0.1*random_state.standard_normal((T))</span>
    <span class="n">c</span> <span class="o">=</span> <span class="mf">0.8</span>
    <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">T</span><span class="p">):</span>
        <span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">+=</span> <span class="mf">0.4</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="mf">0.4</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">c</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">]</span>
        <span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">c</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="p">,</span><span class="mi">3</span><span class="p">]</span>
        <span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="mf">0.6</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="mf">0.3</span><span class="o">*</span><span class="n">data</span><span class="p">[</span><span class="n">t</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="c1">#+ c*data[t-1,3]</span>
    <span class="n">dataframe</span> <span class="o">=</span> <span class="n">pp</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">var_names</span><span class="o">=</span><span class="p">[</span><span class="sa">r</span><span class="s1">&#39;$X^0$&#39;</span><span class="p">,</span> <span class="sa">r</span><span class="s1">&#39;$X^1$&#39;</span><span class="p">,</span> <span class="sa">r</span><span class="s1">&#39;$X^2$&#39;</span><span class="p">,</span> <span class="s1">&#39;Sun&#39;</span><span class="p">])</span>
    <span class="c1"># tp.plot_timeseries(dataframe); plt.show()</span>

    <span class="n">ci_test</span> <span class="o">=</span> <span class="n">CMIknn</span><span class="p">(</span><span class="n">significance</span><span class="o">=</span><span class="s2">&quot;fixed_thres&quot;</span><span class="p">,</span> <span class="n">verbosity</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>   <span class="c1">#</span>
    <span class="c1"># ci_test = ParCorr() #significance=&quot;fixed_thres&quot;)   #</span>
    <span class="c1"># dataframe_nosun = pp.DataFrame(data[:,[0,1,2]], var_names=[r&#39;$X^0$&#39;, r&#39;$X^1$&#39;, r&#39;$X^2$&#39;])</span>
    <span class="c1"># pcmci_parcorr = PCMCI(</span>
    <span class="c1">#     dataframe=dataframe_nosun, </span>
    <span class="c1">#     cond_ind_test=parcorr,</span>
    <span class="c1">#     verbosity=0)</span>
    <span class="n">tau_max</span> <span class="o">=</span> <span class="mi">1</span>  <span class="c1">#2</span>
    <span class="c1"># results = pcmci_parcorr.run_pcmci(tau_max=tau_max, pc_alpha=0.2, alpha_level = 0.01)</span>
    <span class="c1"># Remove parents of variable 3</span>
    <span class="c1"># Only estimate parents of variables 0, 1, 2</span>
    <span class="n">link_assumptions</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1">#{}</span>
    <span class="c1"># for j in range(4):</span>
    <span class="c1">#     if j in [0, 1, 2]:</span>
    <span class="c1">#         # Directed lagged links</span>
    <span class="c1">#         link_assumptions[j] = {(var, -lag): &#39;-?&gt;&#39; for var in [0, 1, 2]</span>
    <span class="c1">#                          for lag in range(1, tau_max + 1)}</span>
    <span class="c1">#         # Unoriented contemporaneous links</span>
    <span class="c1">#         link_assumptions[j].update({(var, 0): &#39;o?o&#39; for var in [0, 1, 2] if var != j})</span>
    <span class="c1">#         # Directed lagged and contemporaneous links from the sun (3)</span>
    <span class="c1">#         link_assumptions[j].update({(var, -lag): &#39;-?&gt;&#39; for var in [3]</span>
    <span class="c1">#                          for lag in range(0, tau_max + 1)})</span>
    <span class="c1">#     else:</span>
    <span class="c1">#         link_assumptions[j] = {}</span>

    <span class="c1"># for j in link_assumptions:</span>
    <span class="c1">#     print(link_assumptions[j])</span>
    <span class="n">pcmci_parcorr</span> <span class="o">=</span> <span class="n">PCMCI</span><span class="p">(</span>
        <span class="n">dataframe</span><span class="o">=</span><span class="n">dataframe</span><span class="p">,</span> 
        <span class="n">cond_ind_test</span><span class="o">=</span><span class="n">ci_test</span><span class="p">,</span>
        <span class="n">verbosity</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">results</span> <span class="o">=</span> <span class="n">pcmci_parcorr</span><span class="o">.</span><span class="n">run_pcmciplus</span><span class="p">(</span><span class="n">tau_max</span><span class="o">=</span><span class="n">tau_max</span><span class="p">,</span> 
                    <span class="n">pc_alpha</span><span class="o">=</span><span class="p">[</span><span class="mf">0.001</span><span class="p">,</span> <span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">],</span> 
                    <span class="n">reset_lagged_links</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
                    <span class="n">link_assumptions</span><span class="o">=</span><span class="n">link_assumptions</span>
                    <span class="p">)</span> <span class="c1">#, alpha_level = 0.01)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span>
    <span class="c1"># print(results[&#39;graph&#39;][:,3,:])</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">round</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="s1">&#39;p_matrix&#39;</span><span class="p">][:,:,</span><span class="mi">0</span><span class="p">],</span> <span class="mi">2</span><span class="p">))</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">round</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="s1">&#39;val_matrix&#39;</span><span class="p">][:,:,</span><span class="mi">0</span><span class="p">],</span> <span class="mi">2</span><span class="p">))</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">[</span><span class="s1">&#39;graph&#39;</span><span class="p">][:,:,</span><span class="mi">0</span><span class="p">])</span>

    <span class="c1"># Plot time series graph</span>
    <span class="c1"># tp.plot_graph(</span>
    <span class="c1">#     val_matrix=results[&#39;val_matrix&#39;],</span>
    <span class="c1">#     graph=results[&#39;graph&#39;],</span>
    <span class="c1">#     var_names=[r&#39;$X^0$&#39;, r&#39;$X^1$&#39;, r&#39;$X^2$&#39;, &#39;Sun&#39;],</span>
    <span class="c1">#     link_colorbar_label=&#39;MCI&#39;,</span>
    <span class="c1">#     ); plt.show()</span>

    <span class="c1"># links_coeffs = {0: [((0, -1), 0.7, lin_f)],</span>
    <span class="c1">#                 1: [((1, -1), 0.7, lin_f), ((0, 0), 0.2, lin_f), ((2, -2), 0.2, lin_f)],</span>
    <span class="c1">#                 2: [((2, -1), 0.3, lin_f)],</span>
    <span class="c1">#                 }</span>
    <span class="c1"># T = 100     # time series length</span>
    <span class="c1"># data, _ = toys.structural_causal_process(links_coeffs, T=T, seed=3)</span>
    <span class="c1"># T, N = data.shape</span>

    <span class="c1"># # Initialize dataframe object</span>
    <span class="c1"># dataframe = pp.DataFrame(data)</span>
    <span class="c1"># pcmci = PCMCI(</span>
    <span class="c1">#     dataframe=dataframe, </span>
    <span class="c1">#     cond_ind_test=ParCorr(),</span>
    <span class="c1">#     verbosity=0)</span>

    <span class="c1"># multidata[0][40:100, :] = 999.</span>

    <span class="c1"># dataframe = pp.DataFrame(multidata, analysis_mode=&#39;multiple&#39;,</span>
    <span class="c1">#         missing_flag = 999.,</span>
    <span class="c1">#         time_offsets = {0:50, 1:0}</span>
    <span class="c1">#          # reference_points=list(range(500, 1000))</span>
    <span class="c1">#          ) </span>

    <span class="c1"># pcmci = PCMCI(dataframe=dataframe, </span>
    <span class="c1">#     cond_ind_test=ParCorr(verbosity=0), verbosity=0)</span>

    <span class="c1"># # results = pcmci.run_pcmciplus(tau_max=1)</span>

    <span class="c1"># results = pcmci.run_sliding_window_of(</span>
    <span class="c1">#     window_step=499, window_length=500,</span>
    <span class="c1">#     method=&#39;run_pcmciplus&#39;, method_args={&#39;tau_max&#39;:1, </span>
    <span class="c1">#     &#39;link_assumptions&#39;:{</span>
    <span class="c1">#     0: {(0, -1): &#39;--&gt;&#39;},</span>
    <span class="c1">#     1: {(1, -1): &#39;--&gt;&#39;, (0, -1): &#39;-!&gt;&#39;},</span>
    <span class="c1">#     }</span>
    <span class="c1">#     })</span>

    <span class="c1"># # tp.plot_graph(results[&#39;graph&#39;])</span>
    <span class="c1"># print(multidata[0].shape, multidata[1].shape)</span>
    <span class="c1"># print(results[&#39;window_results&#39;][&#39;val_matrix&#39;])</span>
    <span class="c1"># print(results[&#39;window_results&#39;][&#39;val_matrix&#39;][0][0,1])</span>
    <span class="c1"># print(results[&#39;window_results&#39;][&#39;val_matrix&#39;][1][0,1])</span>

    <span class="c1"># plt.show()</span>

</pre></div>

          </div>
          
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../index.html">Tigramite</a></h1>








<h3>Navigation</h3>

<div class="relations">
<h3>Related Topics</h3>
<ul>
  <li><a href="../../index.html">Documentation overview</a><ul>
  <li><a href="../index.html">Module code</a><ul>
  </ul></li>
  </ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</div>
<script>document.getElementById('searchbox').style.display = "block"</script>








        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="footer">
      &copy;2023, Jakob Runge.
      
      |
      Powered by <a href="http://sphinx-doc.org/">Sphinx 5.0.2</a>
      &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
      
    </div>

    

    
  </body>
</html>